Reference

Troubleshooting

Find your symptom, get the cause and the command. If you only read one thing on this page, read the next paragraph.

Start with Run checks. Open Settings, then Machines and accounts, find the machine, and press Run checks. It reports one row per check with the fix attached, and it never claims something is fine when it could not read it. Most of what follows is that report, explained.

Installing

The install command says Node.js is required

Node 18 or newer is not on the path for the shell you ran the command in. Install it from nodejs.org and check with node --version.

If Node is installed through a version manager such as nvm, it may exist in your interactive shell and not in a background service. Install a system wide Node as well, or point the agent at the right one.

Set TERMDECK_AGENT_TOKEN first

The command was run without its token, usually because it was retyped rather than copied. Go back to the connect wizard and copy the whole line. If the wizard is gone, open the machine card and choose Regenerate token.

The install stops partway with a 404 or a curl error

Usually a network or proxy problem between the machine and Termdeck. Check the machine can reach it at all:

On the machine
curl -fsSL https://termdeck.io/VERSION

If that fails, the machine cannot reach termdeck.io and nothing else will work until it can. On a corporate network, allow outbound HTTPS to that host.

npm fails while installing ws and chokidar

Scroll up in the output for npm's own error, which is the real one. Common causes are a proxy that npm is not configured for, a registry that is unreachable, and a permissions problem in the npm cache.

After fixing it, run the repair command rather than the installer, so a half written install is cleared first:

On the machine
curl -fsSL https://termdeck.io/heal.sh | sh
Windows: the watchdog task was not registered

Task Scheduler denied access, so the agent is running for this session only and will not come back after a restart. Open PowerShell as administrator and run the install command again.

The machine card will keep showing a stops at restart badge until this is fixed.

The machine is offline

It went offline and has not come back

Work through these in order.

  1. Is the machine awake? Sleep is by far the most common answer. A closed laptop is an offline machine.
  2. Does the card carry a warning badge? Then it died at a logout or a restart and the badge names the fix.
  3. Is the service running?
Terminal
# Linux
systemctl --user status termdeck-agent

# macOS
launchctl list | grep termdeck
  1. Can it reach Termdeck? curl -fsSL https://termdeck.io/VERSION
  2. Still nothing? Run the repair command. It reuses the token already on the machine.
It goes offline every time I log out

A systemd user service without lingering. Systemd shuts your user services down at logout unless lingering is enabled. Run this once on the machine:

On the machine
sudo loginctl enable-linger $USER

The installer attempts this and can only fail when sudo needs a password it cannot prompt for, which is normal for curl | sh.

It goes offline every reboot

Nothing is registered to start it. Rerun the installer, on Windows from an elevated PowerShell. The machine card's stops at restart badge disappears once a proper service exists.

The machine shows online but nothing works

Online means the agent is connected, not that the machine can run a turn. The agent brings no coding agent with it. Check the engine rows on the machine card: a machine with no CLI installed, or with one installed but signed out, is connected and useless.

Two agents seem to be running on one machine

Usually an old launch agent left over from an earlier install on macOS. The current installer retires any launch agent pointing at the same files, so reinstalling fixes it. On any platform, the repair command clears the old install before putting a fresh one back.

Engines and models

The model picker is empty, or says it failed to fetch models

This is the most reported symptom and it nearly always has one cause: the CLI is not signed in, so it cannot list models. Run checks names it directly, with the CLI's own reason attached.

On the machine
claude          # starts the Claude Code login
codex login
grok login

If the login is fine and the catalog still fails, the reason string on the check row is the CLI's own and is the thing to act on.

An engine is installed but Termdeck says it is not

Termdeck looks the binary up the way your shell does. A background service does not inherit your login shell's environment, so a CLI that only works after your shell profile has run will not be found.

Name it explicitly in ~/.termdeck/agent.env and restart the agent:

~/.termdeck/agent.env
TERMDECK_CLAUDE_EXE=/full/path/to/claude
TERMDECK_CODEX_EXE=/full/path/to/codex
TERMDECK_GROK_EXE=/full/path/to/grok
Signing in from Termdeck hangs and never finishes

Check whether the machine has two copies of that CLI on the path, for example an npm global and a package manager install. When it does, the lookup that runs turns and the lookup that drives the sign in can land on different binaries, and the sign in never completes.

Remove the copy you do not want, or pin the right one with the executable variables above.

An engine shows as could not check

The machine did not answer the status question. This is not the same as signed out and Termdeck will not treat it as such. It usually clears on its own. If it persists, look at the agent log from the machine card.

Turns

The composer is locked and says the session is in use

Another process is attached to that session, typically a terminal running the CLI on the same chat. Two writers on one transcript would fork it, so Termdeck goes read only instead.

Exit the CLI in that terminal, or start a new chat in the same folder. The composer unlocks by itself once the other process lets go.

A turn will not start

In order of likelihood:

  • The machine is offline. The sidebar and the machine card both say so.
  • The engine is not signed in on that machine.
  • The session is attached to another process, so the composer is locked.
  • A run is already in progress. On a paid plan the message is queued instead of refused.
  • You are on Free and out of monthly browser turns. Approvals, reading, and stopping remain free.
  • You are on Free and already have a session running. Free allows one at a time.
A turn seems stuck with nothing happening

Check for a waiting approval first, in the transcript or on the Approvals page. A blocked run looks exactly like a slow one until you find the card.

If the engine is retrying a failed provider call, the transcript says so with an attempt count rather than sitting silent. If neither applies and it has genuinely stopped moving, press Stop and send the prompt again.

A tool call never happened and nothing was asked

Three candidates:

  • A hard deny refused it. The transcript says which guard and why.
  • A PreToolUse hook in your CLI settings blocked it before Termdeck saw it. Run checks lists armed hooks.
  • A settings file does not parse, so the engine is ignoring it entirely along with everything configured in it. Run checks flags this as a failure, and it is the highest value row on the page.
I closed the tab and lost the run

You did not. Closing a tab, losing a connection, sleeping a laptop, and a Termdeck release all leave the process running on your machine. The agent parks it and replays what you missed when you come back.

A parked run is held for a few minutes with nobody attached. Past that it is reaped, and everything it wrote is still on disk in the transcript.

The context bar says the chat is nearly full

Press Compact, or send /compact. The engine summarises the conversation so far and continues with the shorter version.

Compacting loses detail. If the chat has drifted a long way from what you want, a fresh chat in the same folder is usually better than compacting a long one.

Approvals

It keeps asking me the same thing

Turn it into a rule. Settings, then Approvals, add a rule for the tool with a glob that matches the command, and a maximum risk cap. It stops asking from the next turn.

Keep the glob tight. npm test is a rule; * is a permission mode with extra steps.

My rule does not fire

Three things to check, in order:

  • The risk cap. A rule only fires when the computed risk is at or below its cap. A command that scores high under a low capped rule will still ask.
  • The tool name. The rule must name the tool the engine actually used.
  • The glob. It matches the command for shell tools and the path for file tools.

The rules list shows a match count per rule, so a rule that has never fired is easy to spot.

Termdeck refused something I wanted to run

A hard deny guard tripped. The message names which one. If your work genuinely needs it, for example a chat whose job is provisioning a machine, switch that guard off in Settings, then Approvals and switch it back on afterwards.

Guards cannot be switched off from anywhere else, and no auto allow rule can override one.

My rules stopped applying

Auto approve needs a paid plan. When a trial ends, saved rules are paused rather than deleted, and the settings page says paused instead of pretending they are still in force. They resume the moment you subscribe.

Notifications

Nothing arrives on my iPhone

Safari only allows web push for a site added to the home screen. Add Termdeck from the share menu, open it from that icon, and enable push there. A subscription made in a Safari tab does not carry over.

They worked before and stopped

Browsers expire push subscriptions, especially after a long idle period or a data clear. Toggle push off and on in Settings, then Notifications to register a fresh one for that device.

The tab title shows a count but nothing needs me

The count, the bell, and the Approvals page are all computed from one list, so they cannot disagree. What counts is a waiting permission, a waiting question or plan, and a turn that failed. Open the bell to see the entries.

The interface

My chats are not in the sidebar

Chats appear only for folders you have added. Add them in Settings, then Projects. If chats you started in a terminal are missing specifically, check the visibility switches in Settings, then Chats.

A chat running in a git worktree is folded into its base repository rather than appearing as a separate project.

A chat vanished

Check the Archive page. Auto archive moves anything untouched for the period you set, and nothing is ever deleted. Termdeck does not delete transcripts under any circumstances: they belong to the CLI and live on your disk.

The page looks wrong after an update

A stale cached asset. Do a hard reload. If that does not settle it, Settings, then Data and reset clears this browser's local Termdeck data. Nothing on your machines is affected: layout and preferences are per browser, and everything that matters is on disk.

Add machine is disabled

You are at your plan's device limit. Remove a machine you no longer use, or move to a plan with more room. The dashboard also lists machines currently being refused for being over the cap, since that refusal otherwise happens in a terminal nobody is watching.

When none of this helps

Email [email protected] with as much of this as you have. It is usually enough to answer without a second round trip.

  • The machine name, its platform, and its agent version, all on the machine card.
  • The output of Run checks for that machine.
  • The last part of the agent log, readable from the machine card.
  • Which engine and model, and whether it also fails in a terminal.
  • What you expected, and what happened instead.

The last one matters more than it sounds. "The turn did not start" and "the turn started and produced nothing" are different problems with different answers.