Troubleshooting

When ciresk dev or the Ciresk dev API refuses something, the answer carries a stable code and, almost always, the next command to run. This page starts with the machine check, then walks through the problems people meet most, grouped by symptom. It ends with a reference entry for every code, which is where an error's type link lands.

Run ciresk dev doctor first

Terminal
ciresk dev doctor

doctor checks this machine and prints one line per check, with the fix next to any check that fails. It exits 1 when a check fails, and its next is the fix of the first failed check (ciresk dev up when all pass).

CheckWhat it looks atFix it names when it fails
dns_lookupWhether Node.js resolves a fresh <name>.localhost to 127.0.0.1 or ::1. Passes when Node.js is not installed.ciresk dev setup --resolver (in an elevated shell)
autocrlfcore.autocrlf in this worktree. Fails when it is true, because every text file would sync with CRLF line endings.git config core.autocrlf input (in this repository), then check the branch out again
resolverWhether .localhost points at the per-machine daemon's resolver, on systems that do not resolve *.localhost themselves.ciresk dev setup --resolver (in an elevated shell)
device_keyWhere the device key is kept: the OS keychain, or a file. A key file that others can read fails.chmod 600 <file> on Linux and macOS, an icacls command on Windows
inotifyWhether any service of this worktree's session is at its file watch limit on the session's host. Passes when there is no session yet.The command the session's health names
policyYour organization's dev policy as it applies to you. Shown for information, never a failure.

doctor has no check of its own for your sign-in or the per-machine daemon. When the API refuses it, the inotify line fails with the session could not be read: ... and the fix the error names, and the policy line says not read: ... with the error code in brackets. Look the code up in the reference.

How an error reads

On a terminal, a failed command prints two lines on stderr: the detail with the code (and the request id when the API answered), and the next step.

Code
error: You run your limit of 10 live sessions; stop one you are done with (ciresk dev down in its worktree) (person_session_limit, request req_0192f3c1d2e84b7a9c0d1e2f3a4b5c6d)
next: ciresk dev status --all

With --json, the envelope's error is the problem document and next the next step. The exit code says what kind of failure it was; cli.md has the exit code table. A code the CLI does not know takes its exit code from the HTTP status: 401 is 3, 403 is 4, 429 is 5, 5xx is 8, anything else 2.

The API answers every refusal as application/problem+json:

409 org_session_limit
{
  "type": "https://docs.ciresk.com/docs/dev/troubleshooting#org_session_limit",
  "title": "Limit reached",
  "status": 409,
  "detail": "The organisation runs its limit of 100 live sessions",
  "code": "org_session_limit",
  "request_id": "req_0192f3c1d2e84b7a9c0d1e2f3a4b5c6d",
  "limit": 100,
  "next": "ciresk dev status --all"
}
  • code is stable. For a code of Ciresk dev's own, type is https://docs.ciresk.com/docs/dev/troubleshooting#<code>, an entry on this page. The codes every Ciresk API shares (unauthenticated, forbidden, insufficient_scope, validation_failed, rate_limited, the idempotency and body codes, wrong_region, internal, unavailable) keep https://docs.ciresk.com/errors/<code>; they have an entry here too. The CLI's own errors use the same rule.
  • detail is written for a person. request_id repeats the X-Request-Id response header; include it when you contact support.
  • Fields beyond these are named in each code's entry. When the answer has next, the CLI prints that instead of its own suggestion.

Signing in and keys

  • No sign-in. ciresk dev uses the sign-in ciresk ci auth login stores in the OS keychain, then CIRESK_DEV_TOKEN, then CIRESK_TOKEN. Without one it fails with unauthenticated: run ciresk ci auth login.
  • A sign-in that expired or was revoked answers unauthenticated too. The CLI renews a sign-in by itself before it expires; when the renewal is refused, sign in again. A running session's tunnel closes within 30 seconds, and the daemon picks up the new sign-in by itself.
  • Several organizations signed in for one region: usage with name one with --org. Pass --org <org_id> or set CIRESK_ORG.
  • A key with no Ciresk Dev access: forbidden. A missing permission: insufficient_scope. A call your kind of identity may never make: principal_not_allowed.
  • Another region: wrong_region. A suspended organization: org_suspended.
  • The CLI cannot reach the API because this machine's egress.yaml does not list it: not_allowed, with the row to add.

Starting a session

Connecting with SSH or an editor

File sync

Policy and limits

Budgets

budget_exceeded refuses a new or restarted session when your daily budget or the organization's monthly budget cannot pay for 5 more minutes of it. A running session that runs out of budget is not refused with an error: it stops with the reason budget, and a remote (cloud) session is paused instead when the policy's lifecycle.auto_stop is pause, the default. ciresk dev status says why. See budgets.md.

Egress

egress_denied refuses a session whose template marks a destination as required that a check does not allow; its reason says which check. An optional destination a check refuses is dropped without an error. See egress.md.

Secrets

secrets_unavailable, secret_invalid, value_required, secret_not_found, pull_secret_not_granted. See secrets.md.

Git push

ciresk dev push runs in the session, and its refusals come from the session: push_credential_missing, push_credential_proxied, push_unauthorized, non_fast_forward, forge_unavailable, push_unavailable, push_unsafe_workflows, push_unsafe_path, change_requests_unsupported, no_base_commit, push_refused, not_cloud_writer. A branch change on a remote session is branch_fixed. See git.md.

Rate limits

Every identity has a limit per minute for each class of call, and an address whose credentials keep failing is refused for the rest of the minute. Over a limit the API answers rate_limited. A session raises at most 10 needs an hour, and a person opens at most 30 browser links a minute; both answer the same code. See rate-limits.md for the limits.

How ciresk dev retries a 429

ciresk dev and its MCP tools send a GET, PUT or DELETE, or a POST with an Idempotency-Key, again by themselves after a 429, at most twice, when the wait the answer names (retry_after, else retry_after_ms, else Retry-After, else 1 second) is at most 5 seconds. Otherwise the command exits 5, its detail ends with ; retry in <n> s, and it prints next: wait <n> s, then run the same command again (or the answer's own next). ciresk dev up, tickets, device grants and needs are never sent again on their own. rate-limits.md has the details.

The 429 answer

Over a per-identity limit, the API answers:

HTTP
HTTP/1.1 429 Too Many Requests
Content-Type: application/problem+json
Retry-After: 23
RateLimit-Limit: 120
RateLimit-Remaining: 0
RateLimit-Reset: 23
X-Request-Id: req_0192f3c1d2e84b7a9c0d1e2f3a4b5c6d
JSON
{
  "type": "https://docs.ciresk.com/errors/rate_limited",
  "title": "Too many requests",
  "status": 429,
  "detail": "More than 120 create requests a minute from this principal",
  "code": "rate_limited",
  "request_id": "req_0192f3c1d2e84b7a9c0d1e2f3a4b5c6d",
  "retry_after": 23
}
Field or headerMeaning
retry_after, Retry-AfterSeconds until the window ends, at least 1.
RateLimit-LimitThe limit of the window you spent from, a minute.
RateLimit-RemainingWhat is left in it: 0 on this answer.
RateLimit-ResetSeconds until it resets.
detailWhich limit: More than <n> <class> requests a minute from this principal, where the class is read, create, ticket or write.

The other 429 answers differ slightly:

  • Failed credentials from one address: detail is Too many failed credentials from this address, and the RateLimit-* headers describe that address's window (120 failed answers a minute by default).
  • Needs: detail is A session raises at most 10 needs an hour; the person has the open ones, and retry_after and Retry-After count down to when the oldest of that hour's needs is an hour old.
  • Browser links: detail is Too many browser links in a minute; try again after retry_after seconds, and retry_after and Retry-After count down to when the minute's oldest link leaves the window.

On the last two, the RateLimit-* headers describe your identity's per-minute window, which is not the one you ran out of.

Idempotency keys

POST /v1/dev/sessions/{session_id}/stop, .../pause, .../start and POST /v1/dev/kill accept an Idempotency-Key header of 1 to 255 printable ASCII characters. A successful answer is kept for 24 hours for your identity: the same key with the same method, path and body gets that answer again and nothing runs twice. The same key with another body is idempotency_key_reused; a malformed key is invalid_idempotency_key. A refusal is not kept, so a retry after it runs again. Without the header these calls work as before: each is safe to repeat by itself.

Data export

Exports and erasure are API calls a person makes signed in as themselves; an agent or a key gets principal_not_allowed. See export_unavailable, export_not_found, erasure_not_found, erasure_started and org_erasing, and export.md.

API codes

The entries below are the reference: each gives the HTTP status, when the API returns it, and the ciresk dev exit code. "Exit -" means no ciresk dev command makes that call.

access_changed

Status 409, exit 4. Your path access in the organization's policy narrowed since the session started. From the CLI the session stops; ciresk dev up starts one with your current view. From the browser, open the session again.

already_resumed

Status 409, exit 1. Another session resumed the one you named; resumed_by names it. Resume the newest one, or ciresk dev up --remote.

branch_fixed

Status 409, exit 4. A remote session always writes its own branch, refs/heads/ciresk/<session_id>, so its branch cannot change.

branch_not_in_ci

Status 422, exit 2. A session started from a branch needs a finished Ciresk CI run on a tree for that branch, and there is none. Run ciresk ci run check on it first (next).

budget_exceeded

Status 403, exit 5. The tighter of your daily budget and the organization's monthly budget cannot pay for 5 more minutes of this session. The answer carries scope (person_day or org_month), limit_units, used_units, resets_at and next: ciresk dev usage. A smaller template, a raised budget or the reset lets the next start through.

cell_session_limit

Status 503, exit 8. The region's cell runs its ceiling of live sessions across all organizations; limit, retry_after_ms (60000) and next come with it. Run ciresk dev up again later.

ci_job_not_found

Status 404, exit 2. Ciresk CI shows no job with that id to your organization. Check the id.

ci_job_running

Status 409, exit 1. The CI job has not finished. retry_after is 15 seconds, also in Retry-After. Wait for the job (ciresk ci wait <job>), then ciresk dev ci record <job>.

ci_job_without_tree

Status 422, exit 2. The CI job ran on a delta, not a tree. Run ciresk ci check --json in the session's worktree and record that job.

ci_not_configured

Status 503, exit 8. The installation has no Ciresk CI to start a branch session from or to verify a record with. Ask the operator.

ci_unavailable

Status 503, exit 8. Ciresk CI could not be asked about the branch or the job; nothing was stored. Retry with backoff.

delegated_session

Status 409, exit 4. The session's agents act for its owner in other products, so it takes view members only. Share it with --role view.

device_not_granted

Status 403, exit 4. This device holds no grant on the session, or its signature does not verify. For a session another device created or someone shared with you, run ciresk dev attach <session_id>.

dotfiles_host_not_allowed

Status 403, exit 4. The repository's host is not in the policy's dotfiles.hosts. An admin changes the policy (next).

dotfiles_invalid

Status 422, exit 2. The dotfiles repository is not an https URL with a host name and a path, names a port other than 443, is a model or tool vendor, the install command is wrong, or a credential is not 16 to 8192 bytes without control characters. The detail names the field.

dotfiles_off

Status 403, exit 4. The organization's policy turns dotfiles off. An admin changes the policy's dotfiles field (next).

dotfiles_private_unsupported

Status 422, exit 2. An SSH URL, or a URL with credentials in it, is refused. A private repository is its https URL with a read-only token: ciresk dev dotfiles set --repo <its https url> --token-stdin.

dotfiles_unset

Status 409, exit 2. You stored a dotfiles credential, but you have no dotfiles repository. Set the repository and the token together: ciresk dev dotfiles set --repo <its https url> --token-stdin.

egress_denied

Status 422, exit 4. A destination the template marks as required is not allowed. denied lists the refused host:port; reason says which check refused it:

reasonMeaningWhat to do
vendorThe row names a model or tool vendor, an IP address or a wildcard that may reach one. Sessions reach models and tools through the model proxy and the MCP gateway only.Remove the row.
org_policyThe organization's egress.session ceiling does not cover it.An admin adds it to the policy (next: ciresk dev policy show).
agent_policyAn agent started the session, and egress.agent does not cover it (unset allows nothing).An admin lists it in egress.agent.
noneThe installation's egress.yaml has no row for it under the product dev-session, which a session's own traffic goes out under.The operator adds the row.

erasure_not_found

Status 404, exit -. The organization has no erasure to read or cancel.

erasure_started

Status 409, exit -. The 24-hour grace is over and the erasure has started; it can no longer be cancelled.

export_not_found

Status 404, exit -. No export of your organization has that id.

export_unavailable

Status 503, exit -. The installation has no object store for exports. Ask the operator.

idle_out_of_bounds

Status 422, exit 4. The idle stop you asked for is outside what the organization allows; idle_min_secs and idle_max_secs carry the bounds and next is ciresk dev policy show. Outside 300 to 28800 seconds the request is validation_failed before the policy is read.

licence_ceiling_reached

Status 402, exit 5. The organization's Ciresk Dev plan's limit is reached; limit, product (dev) and next (https://platform.ciresk.com/billing). Existing sessions and data stay readable.

licence_expired

Status 402, exit 5. The organization's Ciresk Dev plan has ended; expired_at, product and next (the billing page). Existing sessions and data stay readable.

licence_not_yet_valid

Status 402, exit 5. The plan has not started; starts_at says when. New sessions start when it does.

licence_unavailable

Status 503, exit 8. The licence source could not be asked and its last answer is too old. Retry after retry_after (30 seconds, also in Retry-After). Reads keep working.

member_not_found

Status 404, exit 2. The session has no member with that id.

member_view_narrower

Status 409, exit 1. The person may not read every path the session holds, so they cannot be a member. See ciresk dev policy show.

need_not_found

Status 404, exit 2. The session has no need with that number. ciresk dev needs --all lists them.

need_not_open

Status 409, exit 1. The need was already answered or dismissed. Sending the same answer again is not an error.

no_checkpoint

Status 409, exit 1. The session you resume from is still running, was killed or has no checkpoint. Start a new one with ciresk dev up --remote.

not_a_member

Status 404, exit 1. Nobody else in the organization goes by that name or e-mail address.

not_allowed

Status 403, exit 4. Only the session's owner, or a member with the right role, may do this; the answer names nothing else. Also: the organization's session list needs dev:audit.read and is not for agents. From the CLI, not_allowed also means a shell or stream your role does not allow, and a host this machine's egress.yaml does not list, in which case the message names the row to add, of the form - {host: <host>, purpose: ciresk dev, products: [dev-cli]}. The installer writes the rows Ciresk's programs need; a deleted row stays deleted.

not_cloud_writer

Status 409, exit 1. The session is local: its files are on your device. It cannot pause, push from the session or take a schedule; ciresk dev down ends it, and git push from the worktree pushes. ciresk dev up --remote starts a cloud one.

not_paused

Status 409, exit 1. Only a paused session starts again, and a killed session never does. ciresk dev up starts a new one.

org_erasing

Status 409, exit 4. Your organization's dev data is being erased and nothing new starts.

org_session_limit

Status 409, exit 4. Your organization runs the most live sessions its policy allows (lifecycle.sessions_per_org); limit carries the number and next is ciresk dev status --all. It is checked before your own limit, so stopping your own sessions may not be enough.

org_suspended

Status 403, exit 4. This organisation is suspended; contact Ciresk support. Every call of the organization's people, agents and keys answers this until Ciresk resumes it.

parameter_immutable

Status 409, exit 4. The worktree's live session runs another value of a parameter only a new session takes; parameters lists them. Run ciresk dev up --recreate.

parameter_invalid

Status 422, exit 2. A --param or --preset is not one the template declares, or its value is not one the parameter takes; findings names each. More than 32 parameters, a name that is not a template name or a value over 256 characters is validation_failed instead.

parameters_changed

Status 409, exit 4. The worktree's live session runs other values of its parameters; parameters lists them. A person's ciresk dev up recreates the session itself; otherwise run ciresk dev up --recreate.

person_session_limit

Status 409, exit 4. You run the most live sessions the policy allows one person (lifecycle.sessions_per_person); your agents' sessions count against you. limit carries the number. Run ciresk dev status --all, then ciresk dev down in a worktree you are done with.

policy_invalid

Status 422, exit 2. The policy document you sent is wrong; the detail names the field.

policy_local_sync_denied

Status 403, exit 4. The organization's policy keeps code off this machine: no session syncs from a worktree. next is ciresk dev up --remote <template>.

policy_version_conflict

Status 409, exit 1. Someone else wrote a version first; version is the current one. Read the policy again and write version + 1.

principal_not_allowed

Status 403, exit 4. This kind of identity may never make this call, whatever its permissions. Only a person signed in as themselves can set secrets or a dotfiles credential, set the policy, promote templates, share a session, open a session in the browser, export or erase the organization's data; an agent and an API key cannot. An agent cannot attach a device to a session either. Run the command as yourself.

product_not_licensed

Status 402, exit 5. The organization has no Ciresk Dev plan; product and next (https://platform.ciresk.com/billing). During the installation's grace period an organization without a plan is let through.

pull_secret_not_granted

Status 422, exit 2. A service pulls its image with a secret the organization does not grant this session; secret names it, and next is ciresk dev secrets set <name> --host <registry> --repo <this repository>.

secret_invalid

Status 422, exit 2. A secret's name or field is wrong; the detail names it. Names starting with ciresk_ are kept for Ciresk dev's own secrets.

secret_not_found

Status 404, exit 1. No secret of that name. ciresk dev secrets list shows the names.

secrets_unavailable

Status 503, exit 8. The installation keeps no session secrets, or its store cannot keep them. Ask the operator.

session_ended

Status 409, exit 1. The session ended or is ending, so it cannot pause or take a schedule. ciresk dev up --remote starts a new one.

session_not_found

Status 404, exit 1. No such session, or not one you can see. The CLI reports it as no_session.

session_not_running

Status 409, exit 1. The session is not placed on a host yet, or has ended. Run ciresk dev status, and connect again once it is ready.

session_too_large

Status 422, exit 4. The template reserves more memory or CPUs than the organization allows one session. memory_bytes and cpus_milli are the template's, max_session_memory_bytes and max_session_cpus_milli the policy's. Lower memory or cpus in .ciresk/dev.yaml.

sharing_ceiling

Status 403, exit 4. The organization's sharing ceiling does not allow that role. See ciresk dev policy show.

ssh_off

Status 403, exit -. The policy allows no shell in the session, so the browser has no terminal either.

stale_epoch

Status 409, exit 1. The session moved to another host while you changed it. Read it again (ciresk dev status) and retry.

target_not_exposed

Status 422, exit -. The port you opened in the browser is not an HTTP port of the session.

template_file_missing

Status 422, exit 2. The promoted version of the template was published before its dev file was kept. Publish it again: ciresk dev templates publish <template>.

template_invalid

Status 422, exit 2. .ciresk/dev.yaml does not compile; findings lists each problem with its path, and next is set when a finding names its own fix. The same code answers when template_digest is not the digest of the file sent. See templates.md.

template_mismatch

Status 409, exit 4. The worktree's live session runs another template or another version of the dev file; session and request show both. Run ciresk dev up --recreate.

template_not_published

Status 403, exit 4. The organization runs only published templates and this dev file is not the version promoted for the repository; promoted names the active version when there is one. A session without a worktree always needs a promoted version. next is ciresk dev templates publish <template>.

template_version_not_found

Status 404, exit 1. No template version with that id. ciresk dev templates list shows them.

too_many_ci_records

Status 409, exit 4. A session keeps at most 500 CI records.

tree_not_in_session

Status 422, exit 2. The CI job ran on a tree this session never applied. Run ciresk dev sync --wait, then ciresk ci check --json in the worktree and ciresk dev ci record <data.id>.

view_unknown

Status 409, recorded in a schedule's last run. A schedule could not start a paused session because the directory does not say the owner's groups and the policy has path rules. Start it yourself with ciresk dev start.

web_ide_off

Status 403, exit -. The policy does not allow VS Code Web.

web_off

Status 403, exit -. The policy does not allow the session in the browser.

web_unavailable

Status 503, exit -. The installation serves no browser preview.

worker_not_found

Status 404, exit 2. No enrolled worker of that name. See hybrid.md.

writer_conflict

Status 409, exit 4. Another session writes this branch; holder names its session_id, principal, writer and when it took the branch. Stop that session, or work on another branch.

Codes every Ciresk API shares

forbidden

Status 403, exit 4. The credential is valid but may not do this. This API key has no dev scopes means the key was created without the product Ciresk Dev: the CLI suggests ciresk ci auth login --profile <name>, a sign-in of your own in a profile of its own, or create a key with that product (see API keys).

idempotency_key_reused

Status 422, exit 2. The Idempotency-Key already answered a request with another body. Use a new key for a new request.

insufficient_scope

Status 403, exit 4. The credential lacks a permission; required_scope names it (for example dev:policy.write). Ask an admin for a role that holds it, or create a key with it.

internal

Status 500, exit 8. Something failed on Ciresk's side. Retry once; report the request_id.

invalid_body

Status 400, exit 2. The request body could not be read.

invalid_cursor

Status 400, exit 2. The cursor is not one this list issued. Start the list again without one.

invalid_idempotency_key

Status 400, exit 2. The Idempotency-Key is empty, longer than 255 characters or not printable ASCII.

invalid_json

Status 400, exit 2. The body is not valid JSON.

invalid_query

Status 400, exit 2. The query string does not fit the operation's parameters, for example a limit that is not a number. The detail names the parameter.

payload_too_large

Status 413, exit 2. The body is over 1 MiB. The dev file itself is at most 256 KiB.

rate_limited

Status 429, exit 5. Over a rate limit; retry_after and Retry-After say how long to wait. See Rate limits for what the CLI does with it.

unauthenticated

Status 401, exit 3. No credential, or an invalid, expired or revoked one (Authorization: Bearer is required, The credential is missing, invalid, expired or revoked). Sign in with ciresk ci auth login, adding --profile <name> for a named profile.

unavailable

Status 503, exit 8. A service Ciresk dev depends on did not answer. Retry with backoff.

unsupported_media_type

Status 415, exit 2. The body is not sent as application/json.

validation_failed

Status 422, exit 2. A value is out of its pattern or range; the detail names it.

value_required

Status 422, exit 2. A new secret needs its value, and so does a change that moves its hosts, header or purpose or widens its repositories, templates or agent sessions. Send the value again on stdin.

wrong_region

Status 421, exit 3. Your organization lives in another region; region names it. Pass --region <region> or set CIRESK_REGION. The CLI does not retry in the other region by itself.

Codes from the CLI and the session

These come from ciresk dev itself or from the session it talks to, not as an HTTP answer. "Exit" is the CLI's exit code.

agent_exit_unavailable

A pending session's reason, not a refusal. Your organization gives agents their own egress exit, and no online dev host runs a release that enforces it, so the session waits for one that does rather than give the agent the person's egress. ciresk dev status shows the reason.

browser_closed

Exit 1. The session's browser closed or gave no answer. Retry.

cancelled

Exit 6. You interrupted the command, or did not confirm a kill.

change_requests_unsupported

Exit 1. The forge cannot open pull requests from the session. Run ciresk dev push without --pr, then open the pull request on the git host.

client_stream_limit

Exit 5. This client holds as many open streams to the session as it may. Close idle clients, then retry after retry_after_ms.

container_sealed

Exit 4. The container may not be entered with this role or policy.

cwd_invalid

Exit 2. ciresk dev exec --cwd named a path that is not a directory inside the worktree.

daemon_unavailable

Exit 8. The per-machine daemon is not answering. Run ciresk dev doctor.

device_key_exposed

Exit 4. The device key file can be read by others; the message names the chmod or icacls command that fixes it.

diagnostics

Exit 1. The generation you waited for failed to build; the errors come with it. ciresk dev diagnostics shows them.

editor_not_found

Exit 1. ciresk dev code could not start the editor. Check that it is on your PATH, or pick another with --editor code|cursor|windsurf.

elevation_required

Exit 4. ciresk dev setup --resolver needs an elevated shell (on Windows, a PowerShell started with Run as administrator).

env_not_allowed

Exit 2. ciresk dev exec was given an environment variable it may not set. Run it without that variable.

exec_failed

Exit 1. The command ran and failed. Read its stderr, fix, run it again.

exec_not_synced

Exit 7. The session did not apply your latest files within the wait, so the command did not run. ciresk dev status shows the sync.

exec_timed_out

Exit 7. The command ran past its timeout. Raise it with --timeout, up to 60m.

forge_unavailable

Exit 2. The git host did not answer: it is down, or the installation's egress.yaml has no row for it. Push again in a minute; ask the operator if it persists.

host_key_unknown

Exit 1 when the session has not reported its SSH host key yet: retry in a moment. Exit 2 when the key it reported is not an ed25519 key.

ide_unavailable

Exit 2. The session or its host has no browser editor, or it did not start.

Exit 1. A test identity's login set a cookie that outlives the identity's cookie_max_secs. Make the login issue cookies of at most that lifetime, or log in through the browser with ciresk_login <identity> in ciresk dev mcp browser.

identity_without_revoke

Exit 2. The identity declares revoke: none, so its login cannot be revoked; its cookies lapse at their bound, cookie_max_secs after the login.

index_building

Exit 1. The session's code search index is still building. Search again after retry_after_ms.

lazy_workspace_lost

The reason of a lost session: its host restarted while the workspace was still loading lazily, and could not take it back. ciresk dev up in the worktree places the session again.

login_failed

Exit 2. A test identity's login failed: its call answered an error, set no usable cookie, or names a port no service serves. A session compiled before the login was declared needs ciresk dev up --recreate.

no_base_commit

Exit 1. The session's tree came from no pushed commit, so there is nothing to build a commit on. ciresk dev checkpoint keeps the edits as a tree; this session cannot push.

no_capacity

Exit 8. The organization's dev hosts are online but too full for this session. It stays pending and is placed once another session stops. ciresk dev status --all shows what runs.

no_data

Exit 1. ciresk dev reset found no data in the template. Add it to .ciresk/dev.yaml, then ciresk dev up --recreate.

no_next_mcp

Exit 1. The service declares no Next.js dev MCP endpoint, or it did not answer.

no_session

Exit 1. This worktree has no live session, or the session you named does not exist. Run ciresk dev up.

no_source

Exit 2. ciresk dev init found no Compose file or dev container to start from, or the one you named is not a file in the repository. Name one with --from.

no_template

Exit 2. There is no .ciresk/dev.yaml and no template was named. Run ciresk dev up <template> or ciresk dev init.

no_worker

Exit 8. The session is pending and no dev host will place it. On your own workers, start one of your enrolled workers (see hybrid.md); otherwise ask the operator.

non_fast_forward

Exit 1. Someone else pushed to the session's branch; nothing was pushed. The session's next commit builds on its own last push, so fetch the branch, reset or delete it, then ciresk dev push.

no_trunk

A session's failure reason, shown with session_failed: a remote session found no trunk to start from. Push the repository's default branch, then ciresk dev up --remote.

not_found

Exit 2. ciresk dev needs reply or dismiss named a need the session does not have. ciresk dev needs --all lists them.

not_in_sync

Exit 7. The session did not apply your local tree within the wait. Run ciresk dev sync --wait.

not_ready

Exit 7. The session did not become ready within the wait. ciresk dev status --wait waits again.

not_serving

Exit 7. The services did not serve the generation you waited for within the wait. Run ciresk dev wait --gen <n> again.

not_supported

Exit 1. The API this CLI talks to does not serve that call yet.

policy_download_denied

Exit 4. The organization's policy keeps screenshots and page content in the session (download: deny).

policy_ssh_denied

Exit 4. The organization's policy turns SSH off.

port_in_use

Exit 1. A port the session forwards to this machine is held by another process; port, pid and process name it. Stop it, then ciresk dev up.

port_reserved

Exit 1. No process holds the port, but the OS refuses to bind it (on Windows, an excluded port range). Free the port, then ciresk dev up.

push_credential_missing

Exit 1. The session has no secret of purpose git for the forge's host. Store the forge's token (for an SSH forge, its deploy key) with ciresk dev secrets set <name> --purpose git --host <host> --repo <repo>, the value on stdin, adding --agent-sessions when an agent starts the session.

push_credential_proxied

Exit 1. The git secret is one the session's proxy attaches to requests, which a push cannot use. Set it again with --purpose git (the detail names it), then ciresk dev push.

push_failed

Exit 2. The commit could not be built; the detail says which step failed. Try again.

push_refused

Exit 2. The git host refused the push for another reason; the detail says which.

push_unauthorized

Exit 2. The git host refused the session's git secret: it expired, or lacks write access to contents and pull requests. Set the secret again with a new value.

push_unavailable

Exit 1. The installation has no git forge configured, or the session cannot push for the reason the detail names. Ask the operator, or start a new session with ciresk dev up --remote.

push_unsafe_path

Exit 1. The commit would write a .git path. Delete it in the session, then ciresk dev push.

push_unsafe_workflows

Exit 1. A CI workflow on the base branch would run on the session's branch when it is pushed. Give its push trigger branches-ignore: ['ciresk/**'] and drop its create trigger, on the base branch from your own checkout, then ciresk dev push.

query_invalid

Exit 2. ciresk dev search was given a query it cannot run. See ciresk dev search --help.

service_not_ready

Exit 1. A service failed or stalled while starting, or the on-demand service that owns a port did not start; the detail names it. next is ciresk dev logs <service>.

session_failed

Exit 1. The session ended in failed; the detail names the reason, for example secrets_not_delivered or no_trunk. Run ciresk dev up --recreate.

secrets_not_delivered

A session's failure reason, shown with session_failed: the session is granted secrets and they could not be delivered to it, so it does not start without them. The detail says why; check the secrets with ciresk dev secrets list and ask the operator if the store is unavailable.

setup_failed

Exit 2. ciresk dev setup --agents could not write a file; the message names it. Fix or move it, then run setup again.

shell_undeclared

Exit 2. The session's image does not declare the shell or SFTP server a shell needs.

ssh_config_unparseable

Exit 2. ~/.ssh/config holds one ciresk dev marker line without the other. Remove the marker lines, then ciresk dev ssh-config.

ssh_not_found

Exit 1. The system ssh did not start. Install OpenSSH, then ciresk dev ssh.

template_digest_mismatch

Exit 1. .ciresk/dev.yaml changed while the session ran, and its host stopped it. Run ciresk dev up.

timeout_invalid

Exit 2. ciresk dev exec --timeout is outside 1s to 60m.

tunnel_unavailable

Exit 8. The tunnel could not carry the stream. The detail says why, and may name one of the tunnel codes. When it says the daemon does not hold the session, run ciresk dev attach <session_id>; otherwise ciresk dev doctor.

unknown_container

Exit 2. ciresk dev exec named a container the session does not have.

unknown_exec

Exit 1. No exec with that id runs in the session from this machine. ciresk dev status shows the session.

unknown_identity

Exit 1. The template declares no test identity of that name.

unknown_service

Exit 1. The session has no service of that name, or no HTTP port to open. ciresk dev status lists them.

usage

Exit 2. The command line is wrong, or several organizations are signed in for the region (name one with --org). ciresk dev --help and the message say what to change.

volume_unknown

Exit 2. ciresk dev reset named a volume the template's data does not declare.

Template findings

A template that does not pass validation is refused with template_invalid; each finding in findings has its own code and the path it is about. templates.md covers the fields. The findings other pages link to:

egress_host_not_name

An egress row's host is not a DNS name: no IP address, scheme or port. A *. prefix covers every name below it.

egress_ports

An egress row needs at least one port, none of them 0.

reserved_env

A service sets an environment variable that only Ciresk dev sets for the session: any name starting with CIRESK_SECRET_, CIRESK_LOGIN_KEY, CIRESK_LOGIN_TTL, CIRESK_SESSION_EPOCH, REQUESTS_CA_BUNDLE or the model proxy's variables. Remove it from the template.

login_script_later

A test identity declares a script login, which is not available yet. Declare login: {route: /__ciresk/<path>, port} or login: {http: ...} instead.

Tunnel codes

A session or the tunnel refuses a stream with one of these. ciresk dev ssh reports them inside tunnel_unavailable; other commands report them as their own code, exit 2.

starting

The session's container is still starting. Retry after retry_after_ms.

session_not_here

The relay holds no host for the session right now. Retry.

feed_stale

The relay lost its view of the cell for 30 seconds and refuses until it is back. Retry.

draining

The relay is restarting for an update. Retry; the client reconnects.

limit_exceeded

Too many streams on one connection, or connections for one device or person.

killed

The session was killed.

revoked

This device's grant was revoked. ciresk dev attach <session_id> grants it again when you may.

kind_not_allowed

The ticket does not allow this kind of stream: your role, the organization's policy, or a host older than the request. The CLI reports it as not_allowed or policy_ssh_denied.

invalid_ticket

The ticket does not verify, or names another session. The daemon fetches a new one; a lasting one is a sign-in problem.

invalid_device

The device did not prove its key. Run ciresk dev doctor.

resume_buffer_exceeded

A dropped stream could not be resumed: too much was sent while it was away. Run the command again.

resume_timeout

A dropped stream did not come back within the resume window. Run the command again.

closed

The other end closed the stream.

protocol

A message the protocol does not allow at that point, usually a CLI older than the session's host. Update with ciresk update.

e2e_required

The host serves this ticket's streams end to end only, and the client asked for a plain stream. Update the CLI.

e2e_downgrade

The stream was offered without end-to-end protection after a protected one. The CLI refuses it.

e2e_handshake

The end-to-end handshake with the session's host failed. Retry; the CLI fetches a fresh ticket.

e2e_integrity

Bytes on the stream were altered or dropped on the way. Retry.

e2e_pin_stale

The ticket names another certificate than the host's current one. The CLI fetches a fresh ticket.

Codes for Ciresk's own services and hosts

People and agents do not get these from ciresk dev or the API; they appear in the logs of a worker host you run yourself (see hybrid.md) or of Ciresk's own services.

invalid_token

Status 401. A worker's or a service's own token is missing, unknown, expired or revoked. A worker you run enrols again.

lease_not_held

Status 409. A worker reported on a session it no longer holds.

worker_offline

Status 409. The worker is not online for the session it claims.

invalid_dpop

Status 400. A worker's proof for a token exchange does not verify.

form_not_relayed

Status 403. A worker sent a token exchange field it may not relay.

customer_workers

Status 409. The organization runs its sessions on its own workers only, so Ciresk's hosts take none of them.

no_pending_session

Status 409. The organization has no session waiting for a worker.

handoff_used

Status 410. A browser link was used, has expired or does not exist. The person sees This preview has ended.

handoff_mismatch

Status 403. A browser link was made for another preview.

too_many_previews

Status 429. The person holds 20 open previews; they close one and open the link again.

web_session_ended

Status 410. A browser preview has ended.

not_a_tunnel_upgrade

Status 400. A request to the tunnel endpoint was not a WebSocket upgrade with Ciresk-Tunnel: 1. Only ciresk dev and Ciresk's services open tunnels.