Skip to content

Troubleshooting

Fix colour depth, synchronized-output, sandbox, memory, session and version problems in qialike.

Start with the log file: qialike writes to ~/.dsh/qialike.log ($DSH_HOME/qialike.log), and the file rotates to .log.1 past a threshold. Render watchdog recoveries show up as [watchdog] lines and single dropped rows as [row] lines. Settings, credentials, sessions and themes all live under the same $DSH_HOME (default ~/.dsh).

Terminal window
tail -n 100 ~/.dsh/qialike.log

Colours look wrong or washed out

qialike paints hex colours through Ink/chalk, and chalk decides how many colours your terminal can show from the environment. GNOME Terminal/VTE on Ubuntu 24.04 is 24-bit capable but exports no COLORTERM, so it is treated as 256-colour and the palette is mapped by the app. The mapping keeps the page, the raised panels and the composer card on distinct colours, but the exact hexes differ from the theme’s authored values.

If your terminal really is 24-bit and you want the exact hexes:

Terminal window
export COLORTERM=truecolor # the standard signal, understood by every tool
# or, per run:
QIALIKE_COLOR=24bit qialike

Only the exact string truecolor (or TERM=xterm-kitty) counts as 24-bit; COLORTERM=24bit is not treated as 24-bit. QIALIKE_COLOR also accepts 256 and 16.

At 16 colours the composer card and the page are both black on a dark scheme — the palette has no second near-black to offer, so this is a design degradation with no fix. Use it to preview a low-colour terminal, not as a daily driver.

Half-painted frames or a flash of popup chrome

Every frame is bracketed by the terminal’s synchronized output mode (ESC[?2026h … ESC[?2026l). Terminals that do not know the mode ignore it. If yours mishandles it — you see a half-painted frame, or the composer card’s chrome showing through an opening popup — write plain frames instead:

Terminal window
QIALIKE_NO_SYNC=1 qialike

The variable is read only when it is exactly 1, so QIALIKE_NO_SYNC=true has no effect.

Linux: SANDBOX_UNAVAILABLE

Confined bash runs through bwrap (bubblewrap) first, and needs a kernel with unprivileged user namespaces enabled. Where bubblewrap is missing it falls back to qialike’s own Landlock rung, which needs the Landlock LSM enabled in the kernel (≥5.13). Only when both rungs are unavailable does the following happen — that, and not a missing bwrap, is what triggers SANDBOX_UNAVAILABLE:

Terminal window
sudo apt install bubblewrap # Debian / Ubuntu; dnf / pacman elsewhere
cat /proc/sys/kernel/unprivileged_userns_clone # 1 when user namespaces are enabled
grep landlock /sys/kernel/security/lsm # the fallback rung

The app still boots and every non-shell tool works, but each workspace-write / read-only bash call fails closed instead of running unconfined. Only danger-full-access runs. Where the executor offers no kernel confinement at all, per-call shell approval takes over instead — the prompt states that the command has your full user authority. See Permissions for the trade-offs and the fix message.

Memory keeps growing

The runtime is Bun/JSC, which does not return freed pages eagerly. RSS creeps up with use and then plateaus — it is GC policy, not a leak. Reference numbers across the whole process tree, after 12 seconds idle: ~250–290 MB peak while starting the hero, ~330–345 MB while loading a very large session, settling at ~170 MB (hero) to ~225 MB (a long conversation) resident.

  • ≥1 GB of RAM recommended. 512 MB works but is tight; below 512 MB is unsupported.
  • On a constrained box, the supported mitigation is continuous collection:
Terminal window
BUN_JSC_collectContinuously=1 qialike

That keeps RSS down during the same workload at the cost of more frequent GC pauses.

The screen looks frozen while the agent works

It probably is not: while a run is in progress the bottom status bar keeps changing (phase and elapsed seconds, the current tool name, and Ns since last event once the agent is silent for 4+ seconds). If the render loop itself stalls, a watchdog force-repaints and logs a [watchdog] line; any keypress revives the screen immediately. A message whose rendering throws degrades only that row to a ⚠ row dropped warning rather than freezing the UI.

A session resumed when I did not expect it

Auto-resume on every launch is opt-in and should be false unless you turned it on. Check ~/.dsh/qialike.json:

~/.dsh/qialike.json
{ "resume_last": false }

QIALIKE_RESUME_LAST=1 turns it on, and when set at launch the value is persisted into the config file, so an experiment with the variable outlives the shell. Set it to 0 (or remove the key) to go back to a fresh session on every launch.

Remember the two explicit paths: qialike resume continues the newest session in the current directory, and --resume <sessionId> opens one specific session. If a directory seems to have the wrong “newest” session, it is last-activity order — /sessions lists them newest first and lets you pick another, rename, pin or delete.

Terminal too small

On a short terminal the app paints a “terminal too small” notice and ignores all input, including Ctrl+C, until the window is tall enough: this surface needs at least 14 rows (and ≥110 columns before the right-hand Steps panel appears automatically). Resize the window (or the font) and the surface returns. Full-screen dialogs such as /help remain usable at any height.

Corrupt session log

qialike web runs the installed dsh CLI, and both sides read and write the same ~/.dsh/sessions logs. An older dsh reader can reject the newer range-compressed sourceEventSeqs as corrupt history (SessionPersistenceCorruptionError). Install a dsh at least as new as the harness version embedded in your qialike build (npm install -g @deepseek-ai/dsh); qialike web preflights this and prints the matching install command, exiting without starting the server when the version differs.

Copy and paste

qialike does not read the terminal’s own selection: copying (release a drag, or Ctrl+Y) and pasting (Shift+right-click in a dialog) both go through platform clipboard tools. macOS and Windows ship those; Linux does not — so on Linux “copy/paste does nothing” is almost always a missing tool, not a qialike defect.

Linux: check the session type, then install the matching tool

Terminal window
echo $XDG_SESSION_TYPE # wayland or x11
Terminal window
# Wayland
sudo apt install wl-clipboard # provides wl-copy / wl-paste
# X11
sudo apt install xclip # or xsel

On Fedora / RHEL use dnf, on Arch use pacman -S.

Two traps worth knowing:

  • On Wayland, xclip alone is not enough. X11 tools read the X selection, which is usually empty in a Wayland session — you can copy, but pasting reports clipboard is empty. Install wl-clipboard.
  • On X11, having wl-clipboard installed is harmless. qialike tries wl-paste → xclip → xsel and falls through when one fails, so installing both is fine.

Do not test with a bare xclip -o: it reads PRIMARY (the middle-click buffer), not the clipboard Ctrl+V uses. Pass the flag:

Terminal window
wl-paste --no-newline # Wayland
xclip -o -selection clipboard # X11

If that prints what you just copied, the tool side is working.

Symptoms and fixes

SymptomCause and fix
The status bar shows clipboard unavailable — no clipboard tool found (install wl-clipboard, xclip or xsel)No tool is installed at all. Install one as above.
The status bar shows clipboard is emptyA tool ran but the selection it read was empty. Typical on Wayland with only xclip installed — add wl-clipboard.
A drag-copy flashes Copied: …, but nothing pastes elsewhereNo tool was available, so the copy went through the OSC 52 fallback and your terminal does not support or enable it. Installing wl-clipboard / xclip restores the native path.
Right-clicking in a dialog does nothingThat is deliberate: a plain right-click is too easy to hit by accident and does not paste. Use Shift+right-click.
A drag selects the wrong textThe TUI turns mouse tracking on, so the terminal does not handle selection itself. A drag anchored in the message column keeps selecting across columns; one anchored in the Steps sidebar selects only that sidebar.

Pasting without installing anything

The terminal’s own paste shortcut (Cmd+V on macOS; usually Ctrl+Shift+V on Linux and Windows terminals, occasionally Ctrl+V or Shift+Insert) uses bracketed paste — the terminal reads the clipboard itself and none of the tools above are involved. It is the quickest path when you are in a hurry; it only solves pasting in, though — copying still needs a tool or OSC 52.

Copying

  • Drag, then release: the exact highlighted cells are written, independent of the terminal’s own selection.
  • Ctrl+Y: the keyboard equivalent for the current selection (useful on terminals that drop the release event, such as macOS Terminal.app).
  • On success the status bar briefly shows Copied: <preview>, with a character count for long selections. The full text goes to the clipboard, untruncated.
  • Write order: pbcopy on macOS; clip on Windows; wl-copy → xclip -selection clipboard → xsel --clipboard --input on Linux; if none is available it falls back to OSC 52 (supported by iTerm2, Kitty, Alacritty and Windows Terminal — macOS Terminal.app does not, which is why it needs pbcopy).

Pasting

  • Pasted text is sanitised first: escape sequences and control bytes are stripped (clipboard content can come from any program), newlines are folded into spaces in single-line fields, and a single insertion is capped at 4096 characters. On success the status bar shows pasted N chars.
  • Reading the clipboard needs a platform tool (only the Shift+right-click path): macOS ships pbpaste, Windows ships powershell.exe, Linux is covered above.
  • Pasting an image: drag an image file into the composer (the terminal pastes its path as text), or paste a local image path directly — qialike recognises it, reads the file and attaches it as an [Image: name] chip that is sent as an image content block alongside your message.

Other symptoms

SymptomLikely cause and fix
Model shows not set (hero: No provider yet — use /models to add one)No active provider — its key was removed, or every configured provider is hidden. Add one in /models.
The model runs to its output limit with no bodySend any message to continue, or lower the reasoning effort with Ctrl+T to spend fewer tokens.
The approval dialog never appearsWhen the sandbox can be enforced, usually no tool asks for approval. But where the executor offers no kernel confinement at all, per-call shell approval takes over — the dialog does appear, and its prompt states that the command has your full user authority.
A repository overlay refuses to startA repository-level overlay contains rows that spawn processes. Run qialike plugin list for the state, or qialike plugin trust-overlay to review and trust it.
qialike web refuses to startNo dsh CLI, or its version differs from the harness embedded in this build — install the matching version as the message says.
qialike: command not found (just installed)The PATH line is in your profile, but this shell has not read it — source ~/.bashrc (~/.zshrc on zsh) or open a new terminal.
Terminal too small — keys pausedThe terminal is not tall enough: this surface needs at least 14 rows (and ≥110 columns before the right-hand Steps panel appears). Make the window taller and the keys resume by themselves.
EADDRINUSEThe port is taken. A server-side conflict calls for qialike web --port <n>; a local-only conflict just changes the SSH mapping (-L 8080:localhost:3080) — the server needs no restart and the token URL does not change.
401 dsh web authentication requiredThe address is missing its token — use the URL printed at startup, and do not switch between 127.0.0.1 and localhost.
Automatic updates never arriveEither nobody owns this binary (a checkout build or a hand-unpacked zip is never replaced, and the curl installer’s copy only updates on Linux / macOS), qialike-update.auto is false or "notify", or QIALIKE_DISABLE_AUTOUPDATE=1 is set. On Windows only an npm-installed copy updates automatically. See Updates.
Which requests leave the machine, and how to stop themqialike itself has no analytics or telemetry; the harness’s telemetry is feedback-gated (FEEDBACK_ONLY), so only explicit new feedback releases a bounded session prefix. Disable it with DSH_TELEMETRY_MODE=DISABLED. See Config → Data and responsibility.

Next steps