Troubleshooting
Debug in this order: environment → Hub → authentication → node → runtime → task. If an earlier layer is broken, later errors are usually secondary symptoms.
See the CLI reference for complete syntax, Production deployment for infrastructure, and Runtimes for runtime-specific setup.
Collect a minimal diagnostic first
Run these on the affected machine and from the affected project directory:
anet doctor
anet hub status
anet whoami
anet status
anet node ls
anet info <alias>
anet logs <alias> --followdoctor checks configuration, Hub connectivity, node identity, and local dependencies. Do not begin with doctor --fix; read what it intends to change and back up the affected configuration first.
Before sharing logs, remove tokens, API keys, passwords, cookies, complete environment variables, and private Hub URLs. Do not upload all of ~/.anet, .anet/nodes/*/config.json, or .env.
Installation and startup
requires the Bun runtime / spawn bunx ENOENT / Bun not found
Builds 2.3.0-preview.47 and later (both the latest and preview channels are in that range now) refuse before launch with a clear message:
❌ anet hub start requires the Bun runtime (commhub-server is bun-only …)and exit with code 1.
Older builds without that preflight (such as 2.2.x) crash with a bare Error: spawn bunx ENOENT plus a Node stack trace. If you see that string you are on an old build: install Bun, then run anet upgrade. Check your installed version with anet -v; check where the channels point with npm view @sleep2agi/agent-network dist-tags.
Agent Network CLI requires Node.js ≥ 22.13, and the Hub requires Bun ≥ 1.2:
node --version
bun --version
npm install -g bun @sleep2agi/agent-network @sleep2agi/agent-nodeIf a newly installed command is still missing, open a new shell and inspect PATH. For a global npm EACCES error, use nvm/fnm to manage Node instead of sudo npm or weakening system-directory permissions.
agent-node is not installed / version check failed
agent-node --version
anet upgrade --dry-run
npm install -g @sleep2agi/agent-nodeUpgrade on the selected release channel. Do not copy a fixed preview or package version from an old document. See Versioning and Upgrading.
Port conflict or immediate Hub exit
anet hub status
curl http://127.0.0.1:9200/health
lsof -iTCP:9200 -sTCP:LISTENFirst determine whether the listener is an existing Hub. Stop an anet-managed instance with anet hub stop; do not kill processes by a broad name match. If you change the port, the Hub, CLI, and node configurations must all use the new URL.
Hub and network connectivity
ECONNREFUSED
Verify the Hub locally:
curl http://127.0.0.1:9200/health
anet hub statusThen test the configured URL from the node machine:
curl http://HUB_HOST:9200/healthIf local access works but remote access does not, the Hub may be bound only to loopback, a firewall/security group may block the port, or the URL may be wrong. For cross-machine deployments, bind to a reachable address and protect public access with a TLS reverse proxy.
ETIMEDOUT / DNS / TLS errors
Check resolution, routing, certificates, and proxies from the node machine, not only on the Hub host. Verify that the domain does not point to an old host and that an HTTPS reverse proxy can reach the backend /health endpoint.
SSE connection failed / reconnect loop
First prove that ordinary health and login requests work, then inspect the node log. SSE is a long-lived connection: Nginx/Caddy/load balancers must not buffer the response or impose a short idle timeout. See Production deployment.
The task-push path is established only after the log reports SSE connected. Brief drops reconnect with backoff; persistent failures should be fixed at the proxy or identity layer rather than hidden by repeated restarts.
Login, tokens, and networks
No hub configured
anet init --hub http://HUB_HOST:9200
anet login~/.anet/config.json stores the current Hub, user token, and network. Do not assemble tokens by hand or copy one from another machine.
401 invalid token / auth required
anet whoami
anet login
anet doctorOld tokens become invalid after a Hub database rebuild, token revocation, or switching to another Hub. Log in again before checking nodes. A node must use its own ntok_; do not place a user utok_ in node configuration.
For a legacy node config or rejected token, back up .anet/nodes/<alias>/config.json, read the anet doctor result, and only then decide whether to run:
anet doctor --fixForgotten password
Run on the Hub host:
anet hub admin reset-user --username <username>This generates a new password and user token and revokes old user tokens. Do not delete users, token rows, or bootstrap markers directly; that bypasses auditing and can corrupt related state.
network_id_required / access_denied / permission_denied
network_id_required: no unique network can be inferred. Log in/select the intended network, or passnetwork_idin calls that support it.access_denied/permission_denied: identity resolution succeeded, but the role cannot perform the operation. Ask the network owner to change membership; a global admin is not automatically every network's owner.- Agent Nodes use an
ntok_bound to one network. Do not reuse a node token across networks.
See Tokens and permissions, Roles, and Networks.
Other authentication/network errors
| Error | Safe response |
|---|---|
password must be at least 8 characters / too common | Choose at least eight characters and avoid the weak-password list |
429 / too many attempts | Stop retrying and wait for the indicated window; correct the credential before trying again |
network name already exists | Inspect current networks and choose another name; do not edit the database |
network has N active session(s) | Use anet status, stop the nodes normally, then retry network deletion |
quota exceeded | Use anet network ls and remove unused networks. There is currently no public CLI for changing a user plan/global role; contact the Hub operator and do not promote the user to global admin as a shortcut |
Direct database writes bypass API authorization, auditing, and consistency checks and can corrupt related license or identity state, so this guide does not provide SQL “fixes.”
Agent Node
Node remains offline / receives no tasks
Verify in order:
- The node machine can reach Hub
/health. anet whoamipoints to the intended Hub and network.anet info <alias>shows the correct runtime, working directory, and identity.anet logs <alias> --followeventually reportsSSE connected.- No other process uses the same alias,
node_id, orntok_.
Restart one node safely:
anet node stop <alias>
anet node start <alias>Do not copy a node config.json to another machine. Log in and run anet node create on the target so the Hub issues a separate identity.
Duplicate results / changing runtime / alias_identity_mismatch
This usually means multiple processes or old configs use one identity:
anet info <alias>
anet logs <alias> --follow
tmux lsStop old instances and keep one process. Do not reclaim identity by editing node_id, alias, token, or the Hub database. Use anet node rename for renaming.
Node "<alias>" already exists usually means the current project already has that local config under .anet/nodes/. Inspect it with anet node ls / anet info <alias> before reusing it; do not delete the directory merely to recreate the name.
Wrong working directory
File tools use the node's launch directory. Stop it, enter the intended project, and start again. In Codex TUI co-presence, the thread directory is inherited from the app-server process. Follow Codex TUI co-presence and inspect the full session group, not only the bridge.
A claude-code-cli node created on a remote daemon does not start
When you create a node on a remote machine (a daemon) from the Dashboard, whether it runs depends on how the node authenticates:
| Auth method | Stored in | Works across machines |
|---|---|---|
| API key (DeepSeek / MiniMax / Anthropic, …) | node config + Hub secret vault | yes, it travels with the node |
Claude Code CLI subscription login (claude auth login) | that machine's ~/.claude | no, bound to the machine |
For multi-machine setups prefer an API key: configure vendor, model and key in the Dashboard's provider library and pick that preset when creating the node. If you must use a subscription login, SSH to that machine and run claude auth login once; only then can claude-code-cli nodes run there. anet never copies ~/.claude to another machine for you.
Runtime and model
Confirm that the configured runtime exists on the installed release channel:
anet info <alias>
anet logs <alias> --follow
anet upgrade --dry-run| Symptom | Check |
|---|---|
| Claude/Codex command missing | The corresponding CLI is installed, is in the node process PATH, and is authenticated |
| Vendor 401/403 | API key, envRef target, and ANTHROPIC_BASE_URL belong to the same service |
| Vendor timeout/rate limit | Service status, account quota, and node concurrency; do not burn quota with unbounded retries |
| Long Grok ACP task times out | Check flags.grokAcpTimeoutMs / GROK_ACP_TIMEOUT_MS in the runtime guide |
| Codex co-presence loses history after restart | Upgrade to preview.43+; plain anet node start <alias> reads the saved codexThreadId and performs thread/resume. If an old bridge survives, first run anet node stop <alias> from an external terminal |
opencode-cli can share a TUI: V1 can also run headless, V2 is co-presence only, and V2 is still preview. Steps: OpenCode V2. The shared Grok TUI is experimental; see Grok nodes. Follow Runtimes, not old versions or historical changelog commands.
Logs
The node log looks frozen — is the task still running?
A long task used to write nothing at all between "started" and "done" (longest silence measured: 4492 seconds), so "stuck" and "working" read identically. A running task now writes one line every 30–60 seconds:
[12:34:56] [INFO ] [my-node] in-flight grok primary: loop=3, elapsed=2m 15s, last=tool_call (#7)last= is the runtime's most recent activity. No such line means nothing is advancing — troubleshoot it as a hang. A line means it is still working; wait. Grok's two runtimes (ACP and CLI) emit it today; other runtimes follow later.
The log is full of [grok-stderr] warnings and the real problem is buried
Grok's sandbox refusing a path outside its working directory (path outside Grok runtime cwd) is common and recoverable — the model retries through the symlinked path and the task still succeeds. Known-benign stderr of this kind no longer raises one warning per occurrence; it is folded into one line per turn:
[grok-stderr] known-benign stderr this turn: 12 (path-outside-cwd 12)Anything not in the benign table still warns exactly as before — an unclassified failure is never silenced.
Changing log density
ANET_LOG_LEVEL=debug anet node start <alias> # debug | info | warn | error, default info--log-level, the older LOG_LEVEL environment variable and the node config's logLevel also work, in that order of precedence. An unrecognised value is no longer treated silently as info: it warns once, then falls back to the default.
Tasks and messages
Work does not invoke the model
Executable work must use send_task. send_reply is a task result and send_message is ordinary chat; neither invokes the model again.
anet statusConfirm that the target node is online, the task is in the current network, and the alias is correct. See Task lifecycle for status, retry, and parent-child semantics.
task not found / message not found
The current token/network may not own the object, or a message may belong to another node. Start with anet whoami and anet status; do not bypass network isolation by querying or editing SQLite directly.
Scheduled task did not run
The app's Schedules page (Hub schedules) is documented in Schedules. The commands below are a different feature: Goals and Loops.
anet goal list <alias>
anet info <alias>Recurring goals require an online node and consume real model quota. They are not a high-precision cron service; validate with a conservative interval. Inspect next_wake_at, failure entries, and paused status with goal show / wake-log. See Goals and Loops for the full behavior.
Channels
anet channel status <alias>
anet logs <alias> --followCheck the bot token, pairing/allowlist, target node, and channel runtime. Telegram uses long polling; reverse-proxy webhook settings do not apply to it. See Channels for current support and restart requirements.
Docker
docker compose ps
docker compose logs --tail=200 <service>Check Hub health, persistent volumes, the Hub URL inside the container, token files, and model-credential mounts. Inside a container, localhost refers to that container, not the host.
Do not run docker system prune, docker image prune -a, or broad name-pattern cleanup on a shared host. Resolve containers and exact image references first.
Focused pages
When the layer-by-layer pass above does not settle it, each of these targets one specific shape:
- Is this node still alive — when a dispatched task goes unanswered, answer "can it still do work" first. Includes a table ordered by how much each signal is worth (
status = idlecovers four different realities; only "it answered you" is hard evidence). - Reading
anet doctoroutput — what the four prefixes mean, why the version lines report instead of judging, and which questions it cannot answer. - Connectivity: channels and MCP
- Node stuck in stopping / starting
- Restart a Codex TUI node safely
- Feishu bot receives or answers nothing
FAQ
What is Agent Network? Is it free?
A self-hosted communication layer for multiple agents: CommHub handles identity, tasks and messages; agents discover teammates over MCP and receive tasks over SSE; it does not dictate how an agent reasons. The code is Apache 2.0 and there is no official hosted Hub. For personal use run the Hub on your own machine; across machines or for a team, put it on a machine every node can reach. Choose runtimes and models with the runtime comparison and multi-model configuration.
Where are configuration and data stored?
| Path | Contents |
|---|---|
~/.anet/config.json | current Hub, user token, network |
<project>/.anet/nodes/<alias>/config.json | node runtime, identity and flags |
<project>/.anet/nodes/<alias>/.env | optional node secrets, plain text, should be mode 0600 |
~/.commhub/commhub.db | the Hub's SQLite database |
Never commit .anet, tokens or .env. See Security Design.
Can I expose 9200 / 3000 directly to the internet?
Not recommended. Change the initial password first, then put TLS and access control in front with Caddy / Nginx, and go through the production deployment checklist.
Is PostgreSQL supported?
PostgreSQL support is still in development and does not work yet. The maintained and verified backend is SQLite. The code has a DATABASE_URL=postgres://… entry point, but a Hub configured that way refuses to start. Progress: RFC-039.
Still unresolved
Include the following in an issue:
anet -v, Node/Bun versions, and release channel- runtime, operating system, and deployment method
- minimal reproduction and exact error
- redacted excerpts from
anet doctor,anet info, and relevant logs
Search Issues first. Report security problems through a GitHub Security Advisory, not a public issue.