Exit Codes and Errors
Exit codes
| Command | Code | Meaning |
|---|---|---|
heph | 0 | You left with Ctrl-D or /quit. |
heph | 1 | Heph could not start: config, provider, database, git, or the terminal. The reason is printed. |
heph exec | 0 | The turn ended with nothing left to decide. |
heph exec | 2 | The turn ended short: a call no flag covered, an interrupt, the model's output limit, or changes waiting for review. The reason and the conversation to continue on are the last lines on stderr. |
heph exec | 1 | Heph failed before or outside the turn. |
| anything | 1 | An error, printed as Error: <what>. |
Errors you may see
Each error names what it is about; these are the ones a working setup can produce, and what they mean.
CHECK constraint failed: purpose IN (...) during a repeated-call check An
older database layout reported schema version 10 but did not allow
progress-check API calls. This prevents the automatic progress assessment and
falls back to asking you. Upgrade heph and restart the session: startup repairs
this layout automatically, preserving conversation history and audit data. Do
not delete the database or change the permission limits to fix it.
database has migration ... unknown to this heph Another branch build has
already applied a migration absent from this binary. Use a merged build
containing all applied migrations. Migration timestamps do not make an older or
incomplete build safe to use with the upgraded schema. Do not delete the
database or edit its migration records.
database schema is version 9223372036854775807 This database has been
converted to timestamp-based migration tracking, but the running binary still
uses sequential versions. Upgrade heph to a build with timestamp-ledger support
and all migrations already applied to the database.
config: no provider is configured and none was found in the environment No
[providers] in either config file, and neither ANTHROPIC_API_KEY nor AWS
credentials in the environment. Set one, or write [providers].
config: no profile to use: 2 providers are configured (a, b), the catalog has defaults for a and b, and nothing says which to use
Several providers and no default profile. Pass --profile, set
default_profile, or write [profiles]; heph profiles lists them
(Tiers and Profiles).
config: no profile named "x"; there are: ... --profile,
default_profile, an extends, or the profile a conversation kept names a
profile config does not have. A conversation that kept one you removed can be
moved with --profile.
config: profile p: role title is claimed by tiers fast and extra Each role
goes to one tier of a profile; take it out of one tier's roles.
config: profile p: tier x is not in the profile it extends, so it needs both models and role
A tier the base profile lacks is new, and must say both.
config: profiles extend each other in a loop: a -> b -> a Break the loop
with an extends that ends at a built-in profile.
config: no tier has role coding; add it to a tier's role in config Your
[tiers] cover some roles but not this one. Naming any tier replaces all the
defaults, so cover coding, review, and quick at least.
config: tier X: "p/m" is not provider/model-id, or the provider is unknown, or the model is not in the catalog or the provider's config
Check the id against heph models, and that the provider is in [providers].
config: tier X: entries name different models A tier is one model on
several providers; different models are different tiers.
config: tier X: entries are on providers of different protocols (messages, responses)
A tier's providers must all speak the Messages API (Claude) or all speak the
Responses API (GPT), since a turn keeps one protocol
(Providers). Split them into two tiers.
config: provider X: kind "openai-compat" is not one heph speaks The
catalog lists the provider under a protocol heph has no codec for. If the
endpoint speaks the Responses API, add kind = "responses" to its [providers]
table. The same message names vertex, which arrives in build phase 4.
config: provider X: not in the catalog, so config must give base_url and models
A custom provider needs both.
config: "x": not a tier (...) or a model on a configured provider (...) A
--model or --tier model matched nothing; the message lists what it could
have been. config: --tier x: profile p has no such tier (...) names a tier
the profile does not have.
config: PATH: parsing config: ... unknown field A misspelled key or a key
unsupported by the running heph version. Sections heph does not know are
ignored; keys inside known sections must be right.
cannot reload config; fix it before continuing: ... A live policy refresh
could not read, parse, or merge config. The interactive session pauses the
pending call with the filename and diagnostic. Edit that authoritative file
externally and press r to retry, or s/Esc to stop. Advisory fast-model
help appears separately when available; recovery does not wait for it. Neither
the diagnostic nor guidance is sent to the working model. Non-interactive
execution fails with this error. See
Configuration Files.
provider X: API key: environment variable Y is not set The provider's key
source is empty. Also "cmd" exited N for api_key_command, and
no api_key_env or api_key_command configured for a custom provider without
either.
provider bedrock: no AWS region: set AWS_REGION, region in config, or a region in the AWS profile
Bedrock needs a region and found none.
provider bedrock: AWS credentials expired at ...: they were exported into the environment as fixed values, which nothing can renew
The credentials heph was started with had a fixed expiry, now past. Start heph
again under fresh ones, or use an arrangement that renews itself;
Bedrock Credentials sets up each of the
three.
provider X: HTTP 400: Could not process image The provider rejected an
attached image. Bedrock accepts PNG, JPEG, GIF, and WebP of ordinary dimensions;
a malformed or unusual file fails this way.
provider X: HTTP 429, 5xx, 529, or
API error server_error Rate limited, overloaded, or failing on the
provider's side. heph sends the same request again up to three times, waiting 2,
4, then 8 seconds (or what the provider's retry-after asks, up to a minute),
with a status line for each wait. It does not retry once any of the answer has
been shown, since a second send would repeat it. When the retries run out, the
turn fails with this message; try again. Failover to another provider is not
implemented yet.
shadow: shadow lock held by pid N for 0ns Another live heph owns this
conversation's worktree lease. Close that session before opening the same
conversation here. Shadow observation and publication locks wait for live
holders without a timeout; a lock held by a dead process is broken
automatically.
shadow: git [...]: exit N: ... A git command in the shadow repository
failed; the message carries git's own output. Usually git is missing or too
old (merge-tree --write-tree needs 2.40), or the data directory is not
writable.
terminal: ... The interactive session could not take the terminal: stdout
is not a tty, or raw mode failed.
the interactive session needs a terminal; use heph exec with a prompt for a turn without one
heph with stdout piped.
--continue belongs to the interactive session; heph exec takes its own flags after the subcommand
A session flag was given before a subcommand. Move it after.
A turn that fails
A turn that fails midway, because the provider returned an error or a git step
failed, ends as turn failed: <reason> in the conversation. Its rounds so far
are recorded; the turn is closed as interrupted, and any work it left in the
worktree is offered for review the next time the conversation opens, as for any
interrupted turn.