Skip to main content

Troubleshooting

Most failures here have exactly one cause and one fix. Start with the Mac app, then follow the remote-control checks if the problem is on your phone.

An agent will not start

Saggar checks each provider-roster entry through your login shell before launching it from the new-session menu. If the CLI is missing, the session names it and asks before installing anything. Codex and GitHub Copilot CLI use Homebrew; Claude Code, Antigravity, Pi, and OpenCode each use their own installer. Decline and the terminal remains a normal shell. If the app still calls a command missing from the shell, check Settings ▸ Providers and run the install there.

An agent is not reporting status or permission prompts

Automatic recognition can identify a supported agent without hooks, but lifecycle integration is what reports provider events directly. Install or refresh it in Settings ▸ Providers. Providers without permission-aware hooks keep using the screen fallback; the provider capability matrix lists the exact contract.

A new session cannot open its shell

Saggar uses the login shell configured for your macOS account. If that executable has gone missing, it falls back to macOS's built-in /bin/zsh and explains the repair during onboarding. If neither can run, repair the macOS command-line tools, correct the account's login shell, then reopen Saggar.

An update is available

A Homebrew installation upgrades in a visible monitor so you can read the complete output. A direct installation opens the release download. Use Check for updates… from the app menu to retry a failed automatic check. See Settings and maintenance for the update policy.

Saggar crashed or behaved unexpectedly

Settings ▸ General can reveal or export a diagnostics bundle. It includes app and Mac details, logs, and crash stacks, but excludes terminal text, commands, account data, and tokens. Attach that bundle to a bug report. Automatic crash sharing is separate, sanitized, and on by default.

Your Mac isn't in the list

The phone app asks the relay which Macs are yours, so a Mac appears once it has dialed out and stayed connected. Work down the list:

  1. The app is signed in to the same Marginal Utility account the Mac is signed into. Remote control has no browser client, so signing in on this site doesn't list your Macs.

  2. Remote control is not set to Off in Settings → Remote control. Off means the Mac never dials out, so there is nothing for the relay to introduce.

  3. The Mac is awake and online. Settings → Remote control shows the link's real state — connecting, a named failure, or reachable — rather than just repeating the setting back at you.

  4. The Mac is signed in. A signed-out Mac has no account to be found under, and every pairing against it is refused macSignedOut.

  5. The account has Saggar Pro. The relay refuses a Mac whose account holds no remote subscription, and Settings → Remote control says Remote access needs a Saggar remote subscription. with a link to the pricing page. Already subscribed? Sign in under Account, then turn remote access on.

  6. The relay still accepts the Mac's sign-in. When it doesn't, the pane says Sign in again in Settings → Account. Signing in again restores the link.

There is no QR code to scan

The QR and its link appear only while the relay link is online, because the link names the connection the relay will introduce the phone to. If the Status row says connecting, refused, or a named failure, fix that first and the QR appears on its own. The six-digit pairing code is shown regardless, but it needs the same link to be redeemed.

The pairing code is refused

  • Wrong or stale code. Codes are single-use and renew every five minutes. Take a fresh one from the pane.

  • Different accounts. The device and the Mac have to be on the same account — that is the whole gate. The refusal says which end to fix.

  • Signed out on either end. A phone with no account session is refused deviceSignedOut; a Mac with none is refused macSignedOut. Sign in on the end the refusal names.

  • Remote access is off. The Mac answers remoteOff and the phone says what to turn on: Settings → Remote control on the Mac.

  • “Wait a moment”. The account backend didn't answer, or too many attempts arrived at once. That reads as wait rather than no, deliberately: an outage must not look like a mismatch. Try again shortly.

  • Throttled. Five wrong codes within 30 seconds lock pairing out for 60 seconds, and the refusal quotes the wait. A correct code clears the slate.

  • Busy. The Mac holds at most eight undecided requests. Answer or let the waiting cards lapse, then scan again.

  • Denied or lapsed. Someone at the Mac chose That isn't me, or nobody answered within two minutes. Both settle the request for good; scan again for a fresh one.

Your Mac fell asleep

A sleeping Mac holds no connection, and nothing here can wake it — your Mac dials out to reach the relay, so there is no door to knock on. This is the one dead end that waiting doesn't clear.

Saggar holds the Mac off idle sleep while a paired device might need it. The setting has three values — Never, While plugged in (the default), and Always — and Settings → Remote control says whether it is actually holding, and why not when it isn't: remote access off, nothing paired yet, running on battery, or the setting turned off. Worth a glance before you leave the house rather than after.

The phone app can read the setting at approve and change it at drive, so a Mac left on Never can be corrected from the road while it is still awake. Each change is audited like other remote input.

What the hold can't cover: closing the lid sleeps the Mac whatever any app asks for, and so does the Apple menu's Sleep. The display going dark on its own is fine — that isn't sleep, and your sessions stay reachable through it.

Nothing works, from anywhere

There is no offline path. Your Mac is reached through the relay, so no internet at either end — or a relay outage — means no remote control at all, even with the phone and the Mac on the same Wi-Fi. It is the one cost of never opening a port.

It paired, then bounced back to the pairing screen

A 401 anywhere means the grant is gone. Grants never expire on their own, so one of three things happened: the device was revoked on the Mac, the Mac signed out, or the Mac signed into a different account. The app clears the grant deliberately rather than showing a live-looking screen that refuses every action. Signing the Mac back into the same account brings the grant back; otherwise pair again.

The state looks stale

No heartbeat has arrived recently. Usually the Mac is asleep, or the phone has lost its connection. The app says how old the state on screen is, so a plausible-looking fleet can't be mistaken for a live one, and the stream retries on its own with a widening backoff.

A phone that woke up showing yesterday's state

iOS suspends the live stream the moment the app is backgrounded or the phone locks, and the connection often comes back dead without saying so. Bringing the app to the front rebuilds it and refetches, so the wait is a moment rather than the backoff's.

For the state to arrive while the app is closed at all, you want lock-screen alerts — see alerts.

Alerts don't arrive

Lock-screen alerts need notification permission for the Saggar app in iOS Settings. By default the phone also stays quiet while you are at the Mac. More on alerts.

A link opened this site instead of the app

The pairing QR opens the Saggar phone app when it is installed. On a phone without it, the link lands on this site, which can't pair a device. Install the app, then scan the QR code again.

Actions are missing or grayed out

The tier is doing its job. View can act on nothing and approve cannot type arbitrary text. An armed Mac grants drive, so this is usually an older grant kept at the tier it was given — unpair and pair again. The tier each device holds is shown in Settings → Remote control on the Mac.

Still stuck

Settings → Remote control shows the last eight remote actions — what was asked, by which device, and whether it was answered — which is usually the fastest way to see whether a request arrived at all. The full trail is ~/.saggar/control-audit.jsonl, readable only by your user (mode 0600). The pane also says when entries couldn't be written to that file.

If none of this explains it, choose Report an issue… from the Saggar menu; see report a problem.