Troubleshooting
When something goes wrong, the CLI prints a three-line block: a code, a one-line cause, and a one-line action. Search this page for the code or the symptom you saw. Each entry follows the same shape: Cause, Fix, Prevent (when applicable).
Synopsis
User-facing errors are rendered by formatError in packages/types/src/errors.ts:
✗ INVALID_INPUT: --concurrency must be a positive integer
→ Pass a positive integer, e.g. --concurrency 4.
The Error reference table at the bottom lists every registered code. Entries above cover the symptoms users hit most often — install, provider, personality, session, tool, skill, and channel adapter failures. For a local diagnostics view, run ethos logs summary or ethos logs bundle.
Install and setup
ethos: command not found
Cause · The CLI binary is not on your PATH, or the shell has not picked up the new install yet.
Fix ·
- Open a new terminal. Confirm Node 24:
node --version(ornvm use 24). - Reinstall globally:
npm install -g @ethosagent/cli, then verify withethos --version.
Prevent · Pin Node 24 in .nvmrc for any project that calls ethos from scripts.
CONFIG_MISSING
Cause · The first-run setup wizard never completed, or ~/.ethos/config.yaml was deleted or moved.
Fix · Run ethos setup. The wizard writes a fresh ~/.ethos/config.yaml. For a clean slate, rm -rf ~/.ethos/ first.
CONFIG_INVALID
Cause · The config file parses as YAML but is missing one of provider, model, or apiKey.
Fix · Re-run ethos setup — answers default to the current config — or edit the file by hand and re-run.
better-sqlite3 fails to install
Cause · The native module did not find a prebuild for your platform and could not compile from source.
Fix ·
- Install build tools. On macOS:
xcode-select --install. On Debian or Ubuntu:sudo apt-get install build-essential python3. - Reinstall:
pnpm install --force.
Prevent · Keep better-sqlite3 and esbuild in pnpm.onlyBuiltDependencies so pnpm's security sandbox allows their install scripts.
Provider and API keys
PROVIDER_AUTH_FAILED
Cause · The LLM provider rejected the API key. The key is wrong, the env var is unset, or the key was rotated.
Fix ·
- Re-export the key, e.g.
export ANTHROPIC_API_KEY="sk-ant-..."orexport OPENAI_API_KEY="sk-...". - To persist, run
ethos setup keys. - Sanity-check the key with a raw
curlagainst the provider's/v1/messagesor/v1/chat/completionsendpoint.
Prevent · Store keys in a password manager and inject them via a shell init file — never commit them.
LLM_ERROR
Cause · The provider terminated the streamed response with a hard error (usually a 5xx or a content-policy refusal).
Fix · Re-run the same prompt — transient 5xxs clear on retry. If it repeats, capture the printed cause and file a bug.
STREAM_TIMEOUT
Cause · The provider opened the stream but did not produce a token for longer than streamingTimeoutMs.
Fix · Re-run the request. If your network is slow, raise streamingTimeoutMs in the personality config.yaml.
Prevent · On flaky connections, prefer a smaller model — first-token latency is lower.
Rate-limited by the provider
Cause · You crossed the per-minute or per-day quota for the provider's tier.
Fix · Wait a minute and retry — most limits reset per minute. For development, switch to a cheaper model. For sustained load, configure AuthRotatingProvider from @ethosagent/llm-anthropic with multiple API keys.
Personality
PERSONALITY_NOT_FOUND
Cause · The configured personality id does not match any built-in or ~/.ethos/personalities/<id>/ directory.
Fix ·
- Run
ethos personality listand copy a valid id. - Switch with
ethos personality set <id>, or editpersonality:in~/.ethos/config.yaml. - For a custom personality, check the directory contains
SOUL.md,config.yaml, andtoolset.yaml.
PERSONALITY_READ_ONLY
Cause · You tried to edit or delete one of the built-in personalities. Built-ins are immutable on disk.
Fix · Duplicate first: ethos personality duplicate <built-in-id> <new-id>, then edit the copy under ~/.ethos/personalities/<new-id>/.
PERSONALITY_EXISTS
Cause · The id passed to ethos personality duplicate or personalities.create already names an existing personality.
Fix · Pick a different id, or remove the existing user copy first.
Personality is not hot-reloading
Cause · FilePersonalityRegistry.loadFromDirectory() is mtime-cached on config.yaml. Edits to SOUL.md or toolset.yaml alone do not invalidate the cache.
Fix · touch ~/.ethos/personalities/<id>/config.yaml after editing the other files.
Prevent · Edit config.yaml last so its mtime moves after the other files.
Sessions and memory
Agent forgets context mid-conversation
Cause · getMessages(sessionId, { limit }) returns the most recent N messages — the LLM sees the tail, not the head. Long conversations drop older context.
Fix ·
- Use
/newin chat to start a fresh session when context is stale. - Ask the agent to write key facts to memory: "Remember that X" — they land in
~/.ethos/MEMORY.md. - Raise the message
limitin personality config (costs more tokens per turn).
Prevent · Keep important state in memory, not in conversation. Memory survives /new and session resets.
sessions.db shows the wrong order or duplicates
Cause · Same-millisecond inserts need rowid tie-breaking. The current SQLite store handles this — if you see the symptom, the DB was written by an older build.
Fix · Back up (cp ~/.ethos/sessions.db ~/.ethos/sessions.db.bak), then delete (rm ~/.ethos/sessions.db). A fresh DB is created on the next run.
Prevent · Upgrade the CLI before reusing a database written by a build older than 0.2.0.
Tools and boundaries
Tool 'X' not found
Cause · The named tool is not registered, or it is registered but not in the personality's toolset.yaml.
Fix ·
- In chat, run
/toolsto list every registered tool the personality can see. - Add the tool to
toolset.yamlif you want this personality to use it. - If the tool needs an env var (e.g. an API key), confirm
isAvailable()returnstrue.
TOOL_REJECTED
Cause · A before_tool_call hook chose not to let the tool run. The hook's reason appears in the printed cause line.
Fix · Read the cause string — it names the hook. Adjust the hook config (or the tool call) so the boundary is satisfied.
BoundaryError (fs_reach violation)
Cause · A file tool tried to read or write a path outside the personality's fs_reach allowlist. ScopedStorage raises this; the surface translates it into a user-facing tool error.
Fix · Add the path (or a parent) to fs_reach, or move the file under an existing allowed path. If the path is sensitive on purpose, leave the boundary alone and work on a copy under the allowlist.
Prevent · Default-deny is intentional — broaden the allowlist deliberately, not reactively.
BUDGET_EXCEEDED
Cause · The session crossed a token, tool-call, or cost budget configured on the personality. Session-scoped only in v1.
Fix · Run /new to reset the budget counter, or raise the budget in personality config.
MULTIPLE_IN_PROGRESS (todo tool)
Cause · The todo tool was asked to mark a second item in_progress while another is already in that state. Only one task may be in progress at a time.
Fix · Mark the existing in-progress task done or pending, then flip the new one to in_progress.
Tool results are truncated
Cause · Tool output exceeded the per-call slice of the turn's result budget. ToolRegistry.executeParallel() post-trims and appends [truncated — N chars total]. Default total is 80,000 characters per turn, split evenly across concurrent calls.
Fix · Paginate ("read the file 100 lines at a time"), reduce parallel tool calls, or raise resultBudgetChars in AgentLoop config (raises token costs).
Skills and plugins
SKILL_NOT_FOUND
Cause · The skill id passed to a Skills tab action is not under ~/.ethos/skills/ — often the file was deleted out-of-band.
Fix · Refresh the Skills tab. If still missing, re-install: ethos skills install <slug-or-url>.
SKILL_INSTALL_FAILED
Cause · ethos skills install could not complete. The temp directory is rolled back, so nothing is left half-installed.
Fix · Re-run the install — most failures are network blips. If the source URL is wrong, fix the slug. If repeated, check ~/.ethos/logs/errors.jsonl.
SKILL_EXISTS
Cause · A new skill collides with an existing file under ~/.ethos/skills/.
Fix · Pick a different id, or open the existing skill from the Library panel and edit it in place.
PLUGIN_CONTRACT_INCOMPATIBLE
Cause · A plugin declares a pluginContractMajor not supported by this CLI.
Fix · Upgrade the plugin or the CLI per packages/plugin-contract/MIGRATIONS.md. Check both with ethos plugins list and ethos --version.
Channels and gateway
Duplicate outbound message on a channel adapter
Cause · The gateway dedupes outbound messages with a 30-second TTL, keyed by (sessionId, sha256(content)). The same text within the window is silently dropped.
Fix · For intentional retransmission, vary the text or wait the TTL. To disable, set GatewayConfig.outboundDedupTtlMs: 0 or ETHOS_DEDUP_LEGACY=1 (one-release rollback hatch).
Prevent · Do not roll adapter-local dedup. The gateway is the single dedup path; adapter dedup is a bug.
Telegram or Discord bot does not respond
Cause · The bot's token is invalid or the bot is not added to the channel. Bad tokens used to crash the gateway; the current build catches Bot.start rejections and logs them.
Fix · Re-run ethos setup messaging and paste a fresh token. Check ~/.ethos/logs/gateway.log. Confirm the bot is in the target chat with the required permissions.
TEAM_MANIFEST_INVALID
Cause · team.yaml failed to parse or failed schema validation. The offending field is named in the cause.
Fix · Fix the named field in team.yaml and re-run ethos team start.
Cron and jobs
JOB_NOT_FOUND
Cause · The cron job id passed to ethos cron remove, run, or disable does not exist.
Fix · Run ethos cron list and copy the exact id.
JOB_LOCK_FAILED
Cause · Another cron-mutating command is holding the lock.
Fix · Wait and re-run. If it repeats, check for a stuck ethos cron process and kill it.
CRON_INVALID
Cause · The cron expression failed validation.
Fix · Use a valid 5-field cron expression. Test on https://crontab.guru before re-running.
Error reference
The full list of registered codes. Every code shipped in @ethosagent/types EthosErrorCode appears here.
| Code | Cause | Action |
|---|---|---|
CONFIG_MISSING | ~/.ethos/config.yaml is absent or unreadable. | Run ethos setup. |
CONFIG_INVALID | Config parsed but missing required fields. | Re-run ethos setup, or edit the file. |
PERSONALITY_NOT_FOUND | Personality id does not exist. | ethos personality list and pick a valid id. |
PROVIDER_AUTH_FAILED | LLM provider rejected the key. | Re-export the API key or run ethos setup keys. |
LLM_ERROR | Provider returned a non-recoverable error mid-stream. | Re-run. If repeated, file a bug with the cause. |
STREAM_TIMEOUT | The LLM streamed nothing for the watchdog window. | Re-run; tune streamingTimeoutMs if your network is slow. |
INVALID_INPUT | A required CLI flag is missing or out of range. | Read the printed Usage: and re-run. |
FILE_NOT_FOUND | A path passed to a CLI flag does not exist. | Verify the path and re-run. |
BATCH_INVALID_LINE | A line in the batch JSONL file is malformed. | Fix the named line and re-run ethos batch. |
EVAL_INVALID_LINE | A line in the eval JSONL file is malformed. | Fix the named line and re-run ethos eval run. |
TOOL_REJECTED | A before_tool_call hook blocked the tool. | Adjust the hook config or the tool call. |
TOOL_EXECUTION_FAILED | A tool returned { ok: false }. | Treat the printed cause as the tool's diagnostic. |
SUBAGENT_TASK_DUPLICATED | A delegated task duplicated across the child prompt. | Bug — file an issue with the parent personality and prompt. |
JOB_NOT_FOUND | Cron job id does not exist. | ethos cron list and copy the exact id. |
JOB_DUPLICATE | New cron job uses a taken id. | Pick a different id or remove the existing job. |
JOB_LOCK_FAILED | Another cron command holds the lock. | Wait and re-run; kill stuck ethos cron processes. |
CRON_INVALID | Cron expression failed validation. | Use a valid 5-field expression (see crontab.guru). |
CRON_PERSONALITY_MISSING | The personality named on a cron job no longer exists. | Update the job to a current personality id. |
MCP_TRANSPORT_INVALID | An MCP server entry is missing command (stdio) or url (sse). | Edit the MCP server entry in ~/.ethos/config.yaml. |
REGISTRY_FETCH_FAILED | ethos upgrade could not reach registry.npmjs.org. | Check network. Install manually: npm i -g @ethosagent/cli@latest. |
NETWORK_ERROR | A non-registry network call failed. | Re-run. Check your connection. |
SKILL_INSTALL_FAILED | ethos skills install did not complete. | Re-run; verify the source slug. |
SKILL_NOT_FOUND | Skill id is not under ~/.ethos/skills/. | Refresh the Skills tab; the file may have been deleted. |
SKILL_EXISTS | A new skill collides with an existing file. | Pick a different id, or open and edit the existing skill. |
PERSONALITY_EXISTS | Personality id is already taken. | Pick a different id. |
PERSONALITY_READ_ONLY | Built-in personalities cannot be modified directly. | Duplicate, then edit the copy. |
PLUGIN_CONTRACT_INCOMPATIBLE | Plugin declares an unsupported pluginContractMajor. | Upgrade the plugin or CLI per the migration guide. |
TEAM_MANIFEST_INVALID | team.yaml failed schema validation. | Fix the named field and re-run ethos team start. |
UNAUTHORIZED | A web API request lacks valid auth. | Sign in again from the web UI. |
SESSION_NOT_FOUND | The session id passed to the web API does not exist. | Refresh the session list. |
INTERNAL | An unexpected error escaped to the surface. | Re-run. If repeated, file an issue with the printed details. |
Getting help
When filing a bug, include node --version, pnpm --version, your OS, the full three-line error block, the relevant slice of ~/.ethos/logs/errors.jsonl, and steps to reproduce. Open an issue at github.com/MiteshSharma/ethos/issues or a discussion at github.com/MiteshSharma/ethos/discussions.
See also
- Glossary — every domain term in one place.
- CLI reference — every subcommand and flag.
- Changelog — what changed in each release.