Skip to content
Pagr

Reference

Troubleshooting

Almost everything that goes wrong is one of seven things, and pagr doctor names six of them for you.

Start here#

pagr doctor          # ✓/✗ checklist with a fix for every failurepagr status          # the live picturepagr daemon logs -f  # stream ~/.pagr/logs/daemon.log

pagr doctor checks Node, the permissions on ~/.pagr, the secret store, pairing, the daemon socket, gateway reachability, the codex and claude CLIs, and the launch agent — and exits 5 if any check failed.

Symptom table#

Symptoms and fixes
SymptomLikely causeFix
pagr status says daemon not runningThe launch agent is not installed or not loaded, or it crashed at startpagr daemon install, then pagr daemon logs. For foreground debugging, pagr daemon run.
Gateway stuck on connecting or disconnectedOutbound 443 blocked, a wrong gatewayUrl, or the device was revokedSee below.
pairing failed: pairing code expiredMore than a few minutes passed before you approved in the browserRun pagr connect again for a fresh code.
macOS keeps asking for your login passwordThe device key lives in the login KeychainClick Always Allow; see below.
Codex sessions fail immediatelyThe Codex CLI is not logged incodex login
Daemon logs auth failed or device revokedThis device was revoked from the dashboardpagr logout && pagr connect
Notifications go missing, or the gateway log is full of reconnectsTwo daemons share one PAGR_HOME — usually a launchd agent plus a foreground pagr daemon runpagr daemon status and kill the extra one. The daemon now refuses to start a second instance.

The daemon will not connect#

  1. pagr daemon status — is the launch agent installed and loaded? If it is installed but not loaded, pagr daemon install re-bootstraps it.
  2. pagr daemon logs -n 100 — look for gateway disconnected and its reason:
    • ECONNREFUSED or ENOTFOUND — the gatewayUrl in ~/.pagr/config.json is wrong, often a dev URL on a production pairing. Re-pair with pagr connect --force.
    • ETIMEDOUT — outbound TLS on 443 is blocked by a proxy, VPN or firewall. The bridge only ever makes one outbound WebSocket; no inbound ports are needed.
    • bridge too old; update requirednpm i -g @pagr/cli@latest, then pagr daemon install.
    • auth failed — see revoked device below.
  3. pagr doctor — its gateway check does a raw TCP connect. If that fails while a browser can reach the dashboard, something is intercepting WebSockets.
  4. The launch agent runs with the PATH captured at pagr connect or pagr daemon install time. If you installed Node or an agent CLI afterwards, run pagr daemon install again to refresh the plist.

Pairing code expired#

Codes are short-lived. If you did not approve in time, run pagr connect again — the device key is reused and nothing was registered.

Other pairing failures
MessageFix
could not reach https://api.pagr.devNetwork — or you meant a local stack: pagr connect --api-url http://localhost:4000.
pairing rejectedSomeone declined the request in the dashboard.
already paired as dev_…This Mac already has an identity. Use pagr connect --force, or pagr logout first.

Keychain prompts#

The Ed25519 private key is stored in the macOS login Keychain under the service dev.pagr.bridge. macOS may prompt once when the daemon or pagr connect first reads it. Choose Always Allow so the background daemon can start after a reboot without a prompt.

  • If the prompt keeps returning after every update, open Keychain Access, search for dev.pagr.bridge, and allow all applications under Access Control — or just pagr logout && pagr connect to mint a fresh key under the new binary.
  • pagr doctor shows which store is in use: keyring (native), security-cli (the /usr/bin/security fallback) or file.
  • Never copy secrets.json or the Keychain item to another machine. Pair again instead.

Codex is not logged in#

The bridge drives codex app-server; it never touches your OpenAI credentials. If sessions fail with an authentication error:

codex --version      # must be on the launch agent's PATHcodex login          # completes the login locallypagr daemon install  # restart the daemon so it re-probespagr status          # the codex line should show installed

If codex is installed but pagr doctor says not found on PATH, it lives somewhere the launch agent cannot see — a shell-only PATH entry, usually. Symlink it into /usr/local/bin, or re-run pagr daemon install from a shell where which codex works.

Claude approvals never arrive#

Approvals reach your phone for sessions Pagr started. If you never see them:

  1. pagr daemon status — the socket ~/.pagr/run/daemon.sock must exist.
  2. pagr sessions — is the session actually there? Sessions started outside Pagr, with a plain claude in a terminal, are not steered by the bridge. Only sessions the daemon started or resumed are.
  3. claude --version — update with npm i -g @anthropic-ai/claude-code if it is old.
  4. PAGR_LOG_LEVEL=debug pagr daemon run prints every decision.

Revoked device#

Revoking a device in the dashboard closes its socket and rejects its signatures. The daemon logs auth failed and stops reconnecting. Re-pairing creates a new identity — revoked key material is never reused.

pagr logout    # remove the launch agent, delete the private key, drop configpagr connect   # new key, new dev_… idpagr projects  # still there; the cloud learns the ids on the next connect

Use pagr logout --purge to forget the project registry too, or pagr uninstall --yes to remove ~/.pagr entirely. Exit codes are listed in the CLI reference.