Skip to content

Troubleshooting

Most problems come down to three questions: is the core running, can this client reach it, and is it allowed in. Start there.

apx status asks the core itself. The first line is the version and the commit it runs (code_sha), followed by its uptime, memory, URL and the state of each subsystem:

Terminal window
apx status # the core's version and code_sha, subsystems, crew, devices, access
apx --version # this CLI's own version and commit, without asking the core
apx service status # is the service installed, and does the core answer?

If the commit isn’t the one you expect (say, after an update), the core is still running the old code: restart it with apx service restart, or quit and open the desktop app. In the panel, Settings › Advanced shows the same version and code_sha.

If the core isn’t running at all you’ll see:

❯ apx status
apx: the core is not running (try: apx service install, or pnpm dev)

Start it with the desktop app, apx service install (or apx service restart if the service exists), or pnpm dev from a checkout. If it starts and dies, read its log.

However APX runs (the desktop app, the service, or pnpm dev), the core writes its log to the same file, in the logs folder of its home. One JSON line per event; credentials in them are replaced with [redacted].

SystemThe core’s log
macOS~/.apx/v2/logs/core.log (/Users/<you>/.apx/v2/logs/core.log)
Linux~/.apx/v2/logs/core.log (the service also sends it to journalctl --user -u apx -f)
Windows%USERPROFILE%\.apx\v2\logs\core.log

If you set APX_HOME, it is <APX_HOME>/logs/core.log. When the file passes 20 MB, the core keeps the old one as core.log.1 and starts a new one.

Three ways to read it:

  • In the panel: Settings › Logs shows the newest lines first, with a level filter, a search box and the file’s path to copy.
  • apx logs asks the core (it works for a core on a server too), with -n 200, --level error, --grep text or --json. When no core answers, it reads the file on this computer instead.
  • apx service logs -f reads the file on this computer and follows it.
❯ apx logs --level error -n 2
# ~/.apx/v2/logs/core.log
2026-10-15 09:12:03  ERROR  core  channel stopped  {"channel":"acme"}
2026-10-15 09:14:47  ERROR  output  TypeError: Cannot read properties of undefined

Lines in the Process output source are what the core printed outside its log, like the trace of a crash.

Desktop app versions before this change wrote core.log in the app’s own logs folder (~/Library/Logs/APX on macOS, %APPDATA%\APX\logs on Windows, ~/.config/APX/logs on Linux); older lines stay there.

Only one process can listen on 7440. If another core already holds it (an earlier pnpm dev, the desktop app’s own core, the service), a second core fails to start. apx service install checks first and says so:

a core already answers on http://127.0.0.1:7440 and it is not the service's. Stop it first (it may be `pnpm dev` or the desktop app), then run install again.

Stop the other one, or give this core another port with APX_PORT (the terminal follows APX_PORT and core.env too). The desktop app doesn’t fight over it: if a core already answers on 7440, it uses that one.

Once the core is exposed (LAN or Tailscale) it has a token, and every request needs it or a paired device’s key. The apx command and the desktop app on the same machine read it from <home>/core.env on their own. If you see APX · unauthorized with missing or bad token:

  • You’re using a different home than the core: check APX_HOME, or pass APX_TOKEN explicitly.
  • You’re on another machine: don’t copy the token, pair instead (apx pair on the server). A browser shows Pair this device.
  • The device was revoked: pair it again.

Two more you may meet when changing access by hand:

  • The core refuses to start with refusing to listen on 0.0.0.0 without APX_TOKEN: a non-loopback APX_HOST always needs a token. apx expose lan creates one for you.
  • a request through a proxy needs APX_TOKEN on the core: something (like tailscale serve) forwards requests to a core with no token. apx expose tailscale creates one.

The core reads core.env only when it starts. After apx expose, run apx service restart (the panel restarts its own core when it can, or says Saved: it applies when the core starts again). apx status shows Restart needed while the saved access differs from the running one.

apx expose status also tells you if an environment variable is overriding the file (the environment overrides: APX_HOST, for example): the process environment always wins.

What you seeWhy, and what to do
“That code is wrong or expired”Codes last 10 minutes and work once. Restarting the core also voids them. Ask for a new one.
“Too many wrong codes”Five wrong codes pause pairing for five minutes. Wait, then ask for a new code.
“Your phone cannot reach this core yet”The core only listens on its own computer. Expose it (LAN or Tailscale), restart it and pair again.
The phone can’t connect at allIt isn’t on the same network (LAN) or in your tailnet (Tailscale), or the address is wrong. Try the address in the phone’s browser.

More in Your phone.

Terminal window
apx channels # each channel's state, and its last error
apx channels outbox # what was sent lately: queued, sending, sent, uncertain or failed, with the error
apx pairing # strangers waiting for your approval
  • A stranger gets no answer: by default a new person gets a pairing code and waits for you. Approve them with apx pairing ok <code> (or apx pairing me <code> if it’s you on another address), or tell your secretary.
  • Your own message seems to go nowhere: by default your messages on a channel go to the Home chat, so the answer is there too.
  • A person is blocked: blocked people get no answer. Check apx contacts.
  • A send is uncertain: the core was cut while sending, so it can’t know whether it arrived. It isn’t sent twice.
  • Two APX answer the same bot: don’t run APX v1 and v2 with the same bot. Installing v2 stops v1’s daemon for this reason.

More in Channels.

Terminal window
apx models # each engine, and "(not available)" with the reason when it can't be used
apx models --refresh # ask the engines again
apx models config # the install default, the router chain and its rules
  • An engine is not available: usually a missing key or sign-in. Add it in Settings › Engines and models.
  • The router didn’t fall back: it moves to the next model in the chain only when a model fails before any tool ran in that turn.
  • A model takes too long to start answering: the core waits 45 seconds for the first byte (APX_LLM_TIMEOUT_MS).

More in Models.

Terminal window
apx mcps # every server, its state (ready, needs-approval, error…) and its error
apx mcp check <server> # a connection test: OK or Failed, the time and the tool count
apx mcp tools <server> # what it offers
❯ apx mcp check notes
notes: Failed · 3012 ms · 0 tools
connect ECONNREFUSED 127.0.0.1:3000
  • needs-approval: a server from a project’s .apc/mcps.json runs only once you trust that exact definition: apx mcps trust <project> <server>.
  • A missing key: MCP servers get their secrets by reference; set them in Resources › Variables.
  • Ambiguous server: the same name exists globally and in a project. Add --project <id> and --scope.

More in MCP servers.

Agents drive the browser the desktop app lends. Without the app the core uses its own headless Chrome, which can’t hand control to you and never uses your logins. Errors you may see:

  • no connected node offers "browser" (open the APX desktop app): open the desktop app on the computer that runs the core, or one connected to it over SSH. An app connected by address doesn’t lend its browser yet.
  • no Chrome, Chromium or Edge on this machine: install one for the headless fallback, or point APX_CHROME at it. APX_HEADLESS=off turns the fallback off.

For reading pages and searching, agents also have web_read and web_search, which need no browser at all. More in Browser.

They don’t step on each other:

APX v1APX v2
Port74307440
Data~/.apx~/.apx/v2

v2 never writes v1’s files. Installing v2 with the install script stops v1’s daemon and removes v1’s apx command, because both would answer the same channels; v1’s files stay so you can import them with apx import-v1 or the setup wizard (read-only on v1). apx daemon is v1’s habit: in v2 it explains the apx service commands.

To try something risky, start a second core with its own home, its own port and its secrets in a file, so nothing touches your real data or your Keychain:

Terminal window
# From a checkout
APX_HOME=~/work/apx-scratch APX_PORT=7460 APX_SECRETS=file pnpm dev
# From an installed bundle
APX_HOME=~/work/apx-scratch APX_PORT=7460 APX_SECRETS=file \
~/.apx/v2/app/current/node/bin/node ~/.apx/v2/app/current/apps/core/src/main.ts

Then point the terminal at it:

Terminal window
APX_HOME=~/work/apx-scratch APX_URL=http://127.0.0.1:7460 apx status

A core with its own APX_HOME also leaves the skills of Claude Code, Codex and Cursor alone. Delete the scratch folder when you’re done.

Ask on Discord with the output of apx status --plain and the last lines of the core’s log (check them for anything private first).