Why a connected machine stops serving runs, in the order the causes actually occur, and what to tell the person who owns it.
When the compute is someone's own laptop, its state is user-facing. The person who
owns it is the only one who can wake it, sign it in or restart it, which is why
<ComputeStatus /> exists and why this page is written to be handed
to a user rather than kept for an operator.
Start here, on the machine itself:
Terminal
soba-worker --status
Reports every detected runtime, its version and models, its
cost class, whether it is signed in, an authHint for anything
unusable, and whether the background service is installed and up. It contacts nothing,
so it works while the machine is offline.
The machine shows offline#
In the order these actually happen:
The app is not running. The Soba app keeps itself running as a login item, but a
person who quit it, or declined the permission to start at login, has a machine that
goes quiet at the next reboot. Opening the app fixes it.
A headless worker was started by hand. Run from a terminal it is a foreground
process: it dies with the terminal and does not come back after a reboot.
Terminal
soba-worker install
See Keeping it running.
Linux, and you logged out. A user service stops at logout unless lingering is on, and
on a VPS that is the moment you close the SSH session:
Terminal
sudo loginctl enable-linger $USER
Node moved. nvm, fnm, volta and asdf install per-version binaries, so
.../v24.18.0/bin/node stops existing the day you upgrade Node, and the service fails
at a moment completely disconnected from the change that broke it. Re-run
soba-worker install after a Node upgrade.
The laptop is asleep. Nothing is wrong. Runs fall through to
whatever else the app allows, and the app was told which tier served them.
The machine is up but nothing routes to it#
The CLI is signed out. A signed-out runtime is
withheld rather than advertised and failed at spawn,
so a machine can be perfectly healthy and still offer nothing. --status says so, and
authHint names the fix:
Terminal
claude auth login
The app does not accept what this machine offers. An app declares the
cost classes it will accept. A machine offering only user-key when
the app allows only user-hardware and user-subscription is reachable and still
never chosen.
Two workers, one token. Never run both. They double the capacity Soba believes
the machine has, and runs land unpredictably between them. Accepting the install offer
stands the foreground worker down for exactly this reason.
Runs reach it and fail#
The grant is narrower than the work. With no ~/.soba/policy.json a machine grants
read-only tools inside ~/.soba/workspace, not $HOME, not the launch directory. Every
file operation outside that is refused, correctly. Widen it in
the file you control, or for your own development machine use
soba-worker login --dev --root ..
The policy file is malformed. That is a hard failure, not a silent fallback to the
defaults. Quietly ignoring a policy someone wrote is the kind of bug that ends up
looking like a breach.
A tool needs an answer nobody is giving. With "approver": "local" the prompt is on
that machine's terminal. On an installed service there is no terminal to answer, so
askTools are effectively unavailable. Use "approver": "remote", which is safe
because a yes can only ever select from the machine's own askable set. See
Approvals.
The pairing itself broke#
The message says which, and the wording is deliberate:
|
|
| Invalid pairing token. |
Malformed, unknown, or the secret does not match. Deliberately identical for all three, so probing cannot distinguish a real id from a fabricated one |
| This pairing token has expired. |
Re-pair. Tokens carry a TTL |
| This pairing token was revoked. |
Someone revoked this machine. Re-pair if that was a mistake |
| This pairing token was replaced by a newer one. |
Rotation. Re-pair this machine |
| Refusing to send you to http://… |
The pairing page it was pointed at was not https, and the CLI declined to open it. This is the CLI protecting you from a phishing page, not a bug |
In the Soba app, Disconnect forgets the pairing on that machine; on a headless box
--reset does the same. See Pairing.