deckspace.dev / DeckSpace / docs / troubleshooting

Troubleshooting

Find the symptom, check what the app reports, and follow the recovery steps.

Start with Setup & diagnostics. Installation, login, permissions and project checks are separate: a successful result in one does not prove the others work.

Start with Setup & diagnostics

Open Help → Setup & diagnostics, choose your project and agent, then click Check setup. The checks cover folder access, Git, CLI version, configured MCP connections, the Browser and the test engine. A successful setup check does not prove that your project works. The separate Test CLI button makes a real request using your provider account.

For support, choose Preview support report. Review the JSON before saving it. It contains the running build identity, resource counters, permission preflight and cached CLI/engine checks with their age. Export does not start new CLI or engine probes. Missing checks remain unknown; an available native payload does not mean permission was granted or a physical action succeeded.

Only built-in CLIs checked in the current app process appear in the report. Versions contain the numeric release core; custom names, paths, credentials, raw errors, transcripts and project contents are excluded. Saving writes exactly the report you previewed. Nothing is uploaded automatically. Re-run the relevant setup check and create a new preview if you need a fresh sample.

Inspect a local log when needed

The local event log can help explain a failure after the setup checks. It is separate from the filtered support report; inspect its contents before sharing any excerpt.

PlatformLog file
macOS~/Library/Logs/DeckSpace/jarvis.log
Linux$XDG_STATE_HOME/deckspace/jarvis.log, defaulting to ~/.local/state/deckspace/jarvis.log
WindowsNo dedicated location. The path is derived from HOME, which Windows normally does not set, so the file lands in the system temp directory under DeckSpace-logs.

Embedded newlines are collapsed to , so every event stays on one line and grep works.

An agent CLI is not detected

Symptom. claude --version works in your terminal, but the CLI shows up grey in Detect installed AI CLIs and DeckSpace will not launch it.

Why. A GUI app launched from Finder or the Dock inherits launchd’s environment, not your shell’s. The minimal PATH it gets has no nvm, asdf, mise, Homebrew or cargo shims in it.

DeckSpace already works around this. Once per app launch it runs $SHELL -lic 'printf %s "$PATH"', merges the result with the directories below, caches the whole thing, and uses it for every pane and every probe.

Always searched, whatever your shell says
~/.local/bin · ~/.grok/bin · ~/.opencode/bin · ~/.cargo/bin · ~/.bun/bin · ~/.npm-global/bin · ~/.deno/bin · ~/.volta/bin · ~/.local/share/mise/shims · ~/bin · /opt/homebrew/bin · /usr/local/bin · /usr/bin · /bin

Three things break that workaround:

CauseWhat you seeFix
Your login shell takes longer than 1.5 seconds to print its PATH. The query is killed at that cap so a slow .zshrc can never block the first pane.Only the fixed list above is searched. Anything installed elsewhere is invisible.Register the CLI by absolute path, or move it onto the fixed list.
The CLI installed itself somewhere neither your shell nor the fixed list mentions.Same.Same.
The installer added a new directory to your shell’s PATH while DeckSpace was running.The cached PATH does not include that directory yet. A new binary in an already-searched directory can be found on the next scan.Rescan first. If the installation changed PATH, quit and relaunch DeckSpace, then scan again.

Register it by absolute path. Settings → Custom agent CLIs takes a name, a key, and a binary — the binary field accepts either a bare command or a full path such as /usr/local/bin/goose. An absolute path is checked directly and skips PATH resolution entirely.

Detected, but no version next to it

The detailed CLI probe runs <path> --version with a 3-second cap. A binary can be installed while its version check fails or times out. Setup & diagnostics reports that probe error separately; use Test CLI to check an actual request after confirming your login.

The same trap hits your API keys

An export ANTHROPIC_API_KEY=… in ~/.zshenv is invisible to a GUI app for the same reason. DeckSpace copies missing variables out of your login shell with env -0, under the same 1.5-second cap, and only for keys the app does not already have — PATH, PWD, OLDPWD, SHLVL and _ are always skipped. If your shell is slow to start, nothing is copied and the agent will fail to authenticate with no explanation on screen.

A pane opens on walk-away and sits there

Symptom. Walk-away is on, the pane launches, the agent starts — and then stops at its own permission prompt and waits for a human who has left.

Why. DeckSpace does not implement autonomy. It passes the flag your CLI publishes for it, and five of the built-in eleven publish none.

Agent CLIWalk-away flag
Aidernone — the toggle does nothing
Cursor Agentnone — the toggle does nothing
Droidnone — the toggle does nothing
Copilot CLInone — the toggle does nothing
Ampnone — the toggle does nothing

Fix. Use one of the six that do have a flag — see What walk-away does for the full table — or register the CLI again under Settings → Custom agent CLIs and fill in the Walk-away flag field yourself. A custom agent with that field empty behaves exactly like the five above.

An agent’s command was refused

Symptom. The agent runs something ordinary and gets back a red line beginning ⚠ DeckSpace, or a plain Operation not permitted.

These are two different mechanisms with two different fixes. Read which message you got.

“DeckSpace guard” / “DeckSpace blocked a destructive git”

Agent-driven panes get OPX_GUARD=1 and a shim directory at the front of PATH holding three files: rm, git and sudo. The shims are inert without that variable, so a pane you typed into yourself is unaffected. They parse arguments rather than matching text, so flag spellings do not slip past.

What the agent ranWhat happened
rm -r, rm -rf, rm -rfv, rm --recursiveTargets moved to ~/.opxspace-trash, not deleted. Yellow warning, exit 0 — the agent believes it succeeded.
A recursive rm where some target could not be movedNothing is deleted. Red warning, exit 1.
git reset --hardRefused, exit 1
git clean -f / --forceRefused
git push -f, --force, --force-with-lease, or a +ref refspecRefused
git checkout ., git checkout -fRefused
git restorewith any arguments at allRefused
git switch --discard-changes / -fRefused
git branch -D / --deleteRefused
git stash drop, git stash clearRefused
git worktree removeRefused
git update-ref -dRefused
git reflog expire / deleteRefused
git filter-branch, git filter-repoRefused
git gc --prune=nowRefused
sudo — anythingRefused

Fix. The refusal message prints the absolute path of the real binary. Run the command yourself in a pane you opened by hand, or call that absolute path. Deleted work is not gone: look in ~/.opxspace-trash first.

git restore is the entry that surprises people. It is refused unconditionally, including harmless forms like git restore --staged <file>, because the shim keys on the subcommand and not on the flags after it.

“Operation not permitted”

That is the OS sandbox, not DeckSpace. An agent launched into its own pane runs inside a write fence: reads, execution and network are free, all file writes are denied, and writes are then re-allowed in a short list of places.

Only some panes are fenced

The fence covers agents DeckSpace starts — in their own pane, in a pane it opens for you (swarm builders, Maestro workers, Kanban runs), and work it runs with no pane at all. A terminal you opened yourself is deliberately not fenced, so if you see this error in an agent pane and not in your own shell, that is why. The full table is on the walk-away page.

Writable inside an agent pane
The workspace it is working in
/private/tmp, /private/var/tmp, /private/var/folders, /dev
~/.claude, ~/.codex, ~/.gemini, ~/.config, ~/.cache, ~/.local/state, ~/.npm, ~/.opxspace-trash

Everything else is refused by the kernel — whether the agent writes directly, shells out, uses an absolute path, or runs a script. Another repo on the same machine is outside the fence.

Fix. Move the work into the workspace, or turn Confine agent writes off under Settings → Autonomy for the run that legitimately needs to write elsewhere.

There is no sandbox on this machine

PlatformBackendCondition
macOSsandbox-execavailable when /usr/bin/sandbox-exec exists
Linuxbwrapavailable only if bwrap --version succeeds
Windowsrestricted tokenreported only after the local fence self-test succeeds on this machine
Read the reported backend

The Confine agent writes switch is a preference. It does not create a missing sandbox. Read the explanation under it in Settings → Autonomy: it names the available backend, or states that agents can write anywhere you can. An agent may still launch without a backend.

On Linux, install bubblewrap if needed. On Windows, an unsuccessful local restricted-token test means no fence is reported. Review the machine’s configuration before relying on confinement. The command guard is a separate protection and does not establish a filesystem fence.

The app never offers an update

Open Settings → Updates and press Check for updates. It reports an available version, a successful no-update result, or a connection error. A failed check is not shown as “up to date”. The manual check works even when background checks are switched off.

Background checks run after launch, periodically while the app is awake, and on focus, with a 30-minute minimum interval. Use the visible checkbox to turn them off or on. Nothing installs until you choose Update now; a failed install stays available to retry.

Preview and development builds use manual installation and do not query the public update channel. Linux .deb and .rpm installations also use manual package installation. Download the current package from your delivery link and install it with your package manager. The update panel explains these cases without claiming a successful update check.

Compare the installed version with Updating and the release notes if needed. A detached panel does not run the main window’s automatic check cadence.

The phone remote answers 403

Two entirely different refusals share that status code, and they send you to two different screens. The error.code in the response body is what tells them apart.

CodeWhat it meansFix
forbidden_scopeThe device was not paired with the scope this route needs. The message names it: this route needs the order scope. The five scopes are monitor, order, approve, converse and drive (shown as Type into panes).Pair the phone again. Scopes can be taken away from the device list in Settings → Remote and that takes effect immediately — but they cannot be added there. The checkbox for a scope a device does not hold is disabled on purpose.
forbidden_scope, message this device may not take screenshotsScreen captures are a per-device flag, not a scope, because a capture shows your whole screen and not only DeckSpace.Same — granted at pair time only.
forbidden_permissionThe device does hold the scope. A tool-permission category on the desktop is set to ask or deny, and a confirm arriving from a phone has no prompt anyone is standing at.Set that category to allow on the desktop. The body names it in detail.category.
pairing_closedYou typed a pairing code with no pairing window open, or with Remote switched off.Open Settings → Remote on the desktop and start pairing there first.

Only two categories can produce forbidden_permission, and which one depends on where the order was told to land:

Order targetCategory that must be allow
A board task (the default)Board write
A headless missionShell commands — the mission runs an agent that writes files and runs commands in the repo
The phone sends you to a screen with a different name

The message the phone renders says to set the category in Settings → Permissions. The section is actually titled Tool permissions · pre-authorization. Same screen, and the category labels in it (Board write, Shell commands) match the message exactly.

The other refusals a phone can hit:

StatusCodeCause
401pairing_invalidThe code is unknown, expired, or already used.
409device_limitEight devices are already paired. Remove one first.
409already_decidedThe gate moved on between the list and your tap. Refetch.
429120 requests per minute per device. Five failed authentications lock that device out for 15 minutes.
503renderer_unavailableThe DeckSpace window is closed on the desktop.

A gate never reaches the phone

Symptom. Something is clearly waiting for a human on the desktop, and the phone’s approvals list is empty.

Three of the four gate kinds live only inside the DeckSpace window — the Maestro plan gate, the Maestro question wizard, and mission approvals. They are listed where they can be decided, so while the window is closed they are simply absent rather than shown and un-tappable. Reopen the window and the gate reappears with its original timestamp.

A mission started from a detached Loop panel is invisible to the phone

Every DeckSpace window is its own context. A mission started in a detached Loop panel keeps its approval handles in that window, and the main window never learns about it — so its gate never appears on the phone at all. Detaching the panel after the mission started in the main window is fine.

Fix. Start missions in the main window when you intend to approve them from your phone.

The desktop is also given 4 seconds to answer a phone’s request. An overrun is reported as stalled, not failed — approving a plan starts the whole run, so the decision is applied before the answer comes back. Do not tap twice.

Remote will not start

When the server refuses to come up, Settings → Remote gives a reason. Each maps to a specific fix.

ReasonFix
disabledRemote is off. Nothing is listening.
not_proRemote is part of a subscription. Activate or renew under Plan & license, then turn it on.
no_tailnet_addressPrivate mesh is selected but no address in 100.64.0.0/10 exists. Join the mesh, or switch to Local network. Private mesh never falls back to the LAN on its own.
no_lan_addressLocal network is selected but there is no 10.x, 172.16–31.x or 192.168.x address. Join a network and turn Remote on again.
bind_failedAnother program holds the port. Quit it and turn Remote on again.
listener_stoppedThe server stopped on its own. Toggle Remote off and on; the log has the detail.
no_server_idThe identity your phones use to recognise this machine could not be saved — usually an unwritable app database. Remote refuses to start rather than hand out an identity that changes next launch.

If the mode is This machine only, the server answers on 127.0.0.1 and a phone cannot connect to it directly at all. That is the mode working, not failing. See Phone remote.

Recording will not start or Stop is still cleaning up

Click DeckVoice beside Atlas to show the floating pill. Click the pill to expand its controls, then use the microphone to start and stop recording. Choose Type to turn speech into text. The gear opens quick settings for the mode and transcription engine. For the input device, choose All settings… from the gear menu. Opening the pill alone does not start the microphone.

Another Deck app owns the microphone. Stop recording or always-on listening in the named app, wait for it to finish cleaning up, then try again. A compatible DeckSpace and DeckVoice share one capture slot. If you are using an older DeckVoice build, close it first; older builds do not participate in that coordination.

Cleanup is pending. Press Stop again on the same recording. A timeout does not mean the microphone has closed, so starting another recording is refused until cleanup completes. The app reports readiness only after the audio stream starts. Changing the transcription model does not release the microphone.

Transcription failed after Stop. Retry the retained clip before making another recording. Its audio and partial transcript belong to that recording; an older result cannot consume a newer clip. A device warning may still accompany usable audio.

The hold shortcut works, but there is no audio. Shortcut permission, microphone permission and the selected input device are separate checks. Verify the device with push-button recording first, then test the physical hold key. On macOS, review System Settings → Privacy & Security; a granted screen-recording permission does not grant microphone or Accessibility access.

Linux-only failures

SymptomWhyFix
The tray icon does not exist, and mini-mode hides the app with no way backThe tray needs a StatusNotifierWatcher on the session bus. GNOME removed its tray years ago.Install the AppIndicator and KStatusNotifierItem Support extension. DeckSpace warns once at startup when it detects no host — and stays quiet when it cannot tell, so no warning is not proof of a tray.
App-owned hotkeys and dictation insert are greyed outWayland does not expose the app-owned key and synthetic-typing paths used on X11. A desktop portal binding is separate.For automatic insertion use X11. On Wayland use push-button voice or a granted portal hold-to-talk shortcut; paste the transcript from the clipboard yourself.
Desktop hold-to-talk is not granted or stops after a portal disconnectThe portal has not granted DeckSpace its shortcut, or the session ended. A desktop name or installed interface is not a grant.Turn Atlas on, open Voice settings → Push-to-talk and choose Retry desktop shortcut. Answer the desktop dialog, then choose Dictation or Assistant. Release the key after changing the action. Test the physical hold and microphone separately; a granted binding does not confirm either. Switching Atlas off closes the portal session.
Voice replies are silentNeither paplay nor aplay is installed.Install pulseaudio-utils or alsa-utils. The app says this once, then stops repeating it.
Agents write outside the workspacebwrap is missing, so there is no sandbox backend.Install bubblewrap and check the backend reported under Settings → Autonomy. See above.

Activation and licence

DeckSpace requires a valid licence key and a device-bound activation token for that specific device and licence key. Both are checked offline at every launch.

MessageCauseFix
“This license is already active on … devices”The activation server has reached the licence’s device limit. The signed licence supplies the count; the default is two when no count is included.Remove the licence on another device, or use the device page on deckspace.dev, then activate again. Plan & license displays the applicable device limit.
Renew prompt / subscription lapsedThe Stripe subscription behind the key has ended. Renewal is enforced through the activation token, not the key.Renew, then relaunch so the app re-activates.
“That license key isn’t valid.”The key was rejected outright.Check it pasted whole — the keys are long and wrap in email.
“Couldn’t reach the license server.”No network, or the store is unreachable.Reconnect and try again.
Paid features locked after a long stretch offlineThe activation token expires. The app tries to renew it silently once it is within 10 days of expiry — but that background attempt runs at most once per app launch, so a failed attempt is not retried until you relaunch.Get online and relaunch DeckSpace. One successful refresh restores it.

Smaller things

SymptomCause and fix
“Can’t verify the developer” on first launchConfirm the download came from your DeckSpace delivery link, then follow Apple’s current opening instructions. If macOS reports that the app is damaged or will harm your computer, stop and contact support; do not disable Gatekeeper.
A room shows an error panel instead of loadingIts code chunk failed or took more than 10 seconds. The app already retried once automatically. Press Retry; relaunching also re-fetches it.
“tmux not found” when opening a persistent sessionPersistent sessions are tmux-backed so they survive quitting the app. Install tmux (brew install tmux). Ordinary panes do not need it.
An agent authenticates in one pane and not anotherPanes where the CLI is the direct child have no shell in between to source your dotfiles. See the API-key note under agent CLI not detected.

Still stuck

Preview and save a support report from Setup & diagnostics, then send the reviewed report and a short description of the failure to info@deckspace.dev. Include the steps that caused it. Inspect any additional log excerpt for private information before sharing it.