[Bug]: Embedded terminal doesn't answer Primary Device Attribute query — fish stalls 10s and warns on every shell start
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 23k
- Forks
- 5.9k
- Avg merge
- 11h 14m
- Merged PRs (30d)
- 357
Description
Area: apps/web (may be apps/server — see Notes)
Impact: Major degradation or frequent failure
Version or commit: 0.0.34-nightly.20260810.1061 (desktop AppImage, linux-x86_64)
Environment: CachyOS x86_64, kernel 7.1.6-1-cachyos, KDE Plasma 6.7.4 (Wayland), fish 4.8.1, Node v26.7.0
Steps to reproduce
- Set fish 4.1 or newer as your shell (
chsh -s /usr/bin/fish, or just have T3 Code spawn it). - Launch the T3 Code desktop app.
- Open a terminal in the UI.
- Wait.
Expected behavior
The shell starts and the prompt is usable immediately, as it is in any terminal that
answers the query (Konsole, Ghostty, Kitty, Alacritty, GNOME Terminal).
Actual behavior
The terminal is blocked for a full 10 seconds, then prints:
warning: fish could not read response to Primary Device Attribute query after waiting
for 10 seconds. This is often due to a missing feature in your terminal. See
'help terminal-compatibility' or 'man fish-terminal-compatibility'. This fish process
will no longer wait for outstanding queries, which disables some optional features.
The prompt then appears and the terminal works normally. This happens on every shell
start, so every new terminal costs 10 seconds and opens with an error banner. Optional
fish features gated on terminal capability detection stay disabled for the session.
Cause
Since fish 4.1, fish writes \e[0c (Primary Device Attribute) at shell startup and blocks
waiting for a reply, using it to decide which optional features to enable. Per
man fish-terminal-compatibility, the terminal must respond with a CSI sequence
starting with ? and ending in c; the man page names this exact failure mode:
Failure to implement this will cause a brief pause at startup followed by a warning.
T3 Code's terminal is xterm.js, which does implement DA1 — primaryDa and
DeviceAttributes are both present in the bundle. So the reply is most likely generated
but not delivered back into the PTY at the moment fish asks, rather than missing outright.
A startup race between the server spawning the shell and the web frontend attaching its
onData handler would fit: the terminal works normally afterward, including input, which
means the data path is wired up correctly by the time the user interacts with it.
Flagging that last paragraph as a hypothesis from reading the bundle, not something I
confirmed against the source. What is confirmed is the fish-side behavior below.
Verification
Reproduced fish's side under a PTY harness that deliberately never answers the query,
to isolate it from T3 Code:
[baseline (no env var)] warning_shown=True
[fish_features=no-query-term] warning_shown=False
Also worth noting for anyone attempting a fix in shell config: fish latches feature flags
before sourcing config.fish, so setting the flag there does not work even though
config.fish is sourced before the query goes out. Measured ordering in the same harness —
config marker at output offset 0, \e[0c at offset 102, warning still shown.
Workaround
Export the flag in whatever launches the app, which scopes it to shells T3 Code spawns and
leaves other terminals with capability detection intact:
export fish_features=no-query-term
The commonly suggested set -Ua fish_features no-query-term also silences it, but it is a
universal variable, so it disables the feature in every fish session including terminals
that answer DA1 correctly.
Notes
- Filed against apps/web because xterm.js generates the DA1 reply, but if the gap is in
PTY attach ordering the fix likely belongs in apps/server or the wiring between them. - Only affects fish 4.1+. bash and zsh don't issue this query, which is probably why it has
gone unreported. - A short-term mitigation on your side, if the attach race is hard to close, would be
buffering PTY output until the frontend handler is attached, so early queries aren't
dropped.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Trace the embedded terminal path across apps/web and apps/server, starting with xterm.js DA1 handling and the PTY attach ordering. Reproduce with fish 4.1+ and inspect whether the response is delivered before the frontend handler is attached. Done means fish starts without the 10-second delay or warning while normal terminal input remains functional.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- desktop, devtools
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 58/100