Skip to main content

Troubleshooting

Start with lonca doctor; then find the reason or the error you got below. A denial is an answer, not a failure: the operation is in the log with its reasons, and the reasons say what to do.

lonca doctor​

Doctor summary (lonca 0.2.2):

[✓] Mode: cooperative: the daemon runs as you
[✓] Daemon
✓ socket: /Users/ayse/.lonca/lonca.sock belongs to the daemon
✓ daemon: version 0.2.2, protocol 1
[!] Hooks
! no managed settings at /Library/Application Support/ClaudeCode/managed-settings.json
→ sessions count as unobserved until the hardened installer has run
[✓] Sandbox: seatbelt
[✓] Tools
✓ git: found
✓ lsof: found
[✓] Human
✓ human: ayse
✓ security events: none in the last 24 hours
[✓] Repository demo
✓ log: 6 entries verify
✓ human: ayse is enrolled

! Doctor found issues in 1 category.

The checks are grouped, each group marked with its worst check (✓, ! for a warning, ✗ for a failure), and anything that does not pass says what to do on the line under it (→). A warning leaves the exit code 0, a failure makes it 1; --json gives {"ok", "mode", "checks"}. Colour only on a terminal, never with NO_COLOR or TERM=dumb. Nothing in it prompts: with a Secure Enclave key or a security key and no live session it asks you to run lonca human login first.

CheckNot passingWhat to do
mode/Library/Lonca/daemon.toml or /etc/lonca/daemon.toml is not root-owned, or is writable by othersRun the hardened installer again. The CLI refuses to send a token until it is fixed.
socketno socketStart lonca daemon, or set LONCA_SOCKET to where it listens.
socketit belongs to another userSomeone else's process listens there. Run the hardened installer again; do not work around it.
daemonit does not answerRestart the daemon; its output says why it stopped.
daemonprotocol N, this CLI speaks M (fail), or another version (warn)Use the same release for the CLI and the daemon. After an upgrade, restart the daemon.
hooksnot locked by managed settingsCooperative: a warning, sessions count as unobserved. Hardened: a failure, run the installer again.
sandboxnone foundInstall bubblewrap (Linux). Without it verification runs unsandboxed; a hardened daemon refuses to start.
sudoruns without a password (hardened only)An agent running as you could use it: set Defaults timestamp_timeout=0, or work from a non-admin account. Sessions count as unobserved until then.
gitnot on PATHInstall git.
lsofnot on PATHInstall lsof; without it network use can not be attributed to a session.
humanno identitylonca human keygen <name>.
humancould not open a sessionlonca human whoami; maybe no repository knows this human yet (lonca init, or ask an enrolled human to lonca human enroll you).
security eventsa freeze, an integrity alarm, a write behind the daemon's back, a failed reconcile in the last dayRead the daemon's security.log and lonca log for the entries.
log <repo>does not verify, or ends before the daemon's headRun lonca-audit verify on the store or a pushed copy, and freeze the repository until you know why.
human <repo>not enrolledAn enrolled human runs lonca human enroll.
human <repo>a file key where the repository requires presencelonca human rotate --secure-enclave --repo <repo> (Mac) or --security-key (a FIDO security key).
presencethe key is in hardware and the program that signs with it is missingPut lonca-se next to lonca (Secure Enclave), or install OpenSSH 8.2 or later (security key). With a file key the line only says what this machine could use.
settings <repo>below the hardened profile, on a hardened installA human changes them with lonca policy set (Profiles).
frozen <repo>frozenFind out why (lonca log), then lonca unfreeze "<reason>".

Denials​

lonca prints #SEQ deny: <reasons> and exits 1. The common ones, by what caused them:

The lease​

ReasonWhat to do
lease_missing:<symbol>Lease it (lonca lease acquire), then propose again. lonca lease needed lists what the local changes need and who holds it.
lease_held:<symbol>:<session>:<intent>Another session holds it. Wait (lonca lease interest, or the lease_interest tool), settle it with negotiate, or work on something else.
lease_expired, not_own_lease, unknown_lease_setThe set is gone or not yours: acquire again.
lease_hold_limitHeld past leases.max_hold_minutes while someone waits: finish, or let it go and acquire again.
lease_reserved:<session>, lease_wanted:<session>Freed and reserved for that session, or that session waits first. The answer's details say until when.
lease_freeAn interest in something nobody holds: acquire it instead.
intent_requiredSay what you are doing and why (-i).
shared_offshared leases are off in this repository.
created_since_base:<path>Trunk created that file after your base: lonca sync, then lease and propose.

The proposal​

ReasonWhat to do
claim_mismatch:<field>The claim differs from what Lonca computed. lonca diff (or the preview tool) prints the facts: copy them into the claim.
stale_trunk, unknown_baselonca sync, then propose again.
scope_path:<path>, scope_symbol:<symbol>, scope_op:<op>Outside the session's scope. Leave that file alone, or a human starts a session with a wider scope (--continue <dir> --widen keeps the workspace).
scope_max_files, scope_max_linesToo big for the session: split the change.
unobserved_critical_path, tainted_critical_path, unhooked_critical_pathA critical path (Cargo.toml, .github/**, CLAUDE.md, …) from a session that is not fully observed. See Every change waits for me.
verification_quota:session, verification_quota:dayPast [quota]. The session's does not come back; the day's does at midnight UTC.

The session or the repository​

ReasonWhat to do
session_ended, session_inactive, unknown_session, session_ttlThe session is over. A human continues the workspace: lonca session start --continue <dir>.
session_continued, continue_child_session, scope_widening:<what>That continuation is refused: a session is continued once, a child session is not continued, a wider scope needs --widen.
frozen:<reason>A human unfreezes it once the reason is dealt with.
already_approvedYou approved this one already; it waits for another human.
nothing_pendingThat sequence number does not wait for approval (approved, rejected or withdrawn meanwhile).

A human signature​

ReasonWhat to do
presence_requiredThe repository accepts only keys that prove presence: lonca human rotate --secure-enclave (Mac) or --security-key (a FIDO security key).
not_enrolled, unknown_humanThat key is not enrolled in this repository.
stale_human_signatureThe signature is older than 10 minutes or more than a minute ahead: check the clock.
bad_human_signature, bad_nonce, nonce_reusedThe request was refused as signed. Run the command again; if it repeats, report it.

Anything else is a policy rule's id or a key operation's reason: the rule is in lonca policy show. All codes: docs/protocol.md, "Reason codes".

Errors​

An error means the request never reached the log.

ErrorWhat to do
unauthenticated: unknown session token: …The agent's session ended, expired or got a new token. A human continues the workspace (lonca session start --continue). Restart lonca mcp after that, so it reads the new token.
unauthenticated: login failed: …No enrolled key of that human verifies the signature: wrong --as, or the key was rotated on another machine.
forbiddenA token of the wrong kind or for another repository, or a human the repository does not know.
rate_limitedThe session (with the sessions made from it) is past [sessions] ops_per_minute. The message says when to try again.
busy, closedSend it again.
foreign_keyThe repository is on a daemon key this daemon does not hold: lonca daemon-key recover --repo <name>, or, when your key was lost with it, lonca human recover --repo <name> --recovery-key <file> (Recovery).
integrityThe log does not verify or replay. Do not write to the store; audit it and restore from a backup or a pushed remote.
unsupportedA log format or symbol engine this daemon does not know: upgrade the daemon.
redacted (on lonca fetch)A redacted blob is in trunk's history; Git needs whole objects. Work from a Lonca workspace.

Common situations​

Every change waits for me, and agents can not touch Cargo.toml​

That is cooperative mode: nothing can prove what an agent running as you did, so its sessions are unobserved, every change escalates (unobserved_session), and a change to a critical path is denied (unobserved_critical_path) with nobody to ask. Three ways out:

  • If you do read every change, let critical paths escalate instead of being denied: unobserved_critical = "escalate" under [observation], set with lonca policy set (Running agents). Do not set unobserved_is_tainted = false: the review goes with the denial.
  • Install hardened mode, where Claude Code's hooks and sandbox are locked and sessions are observed (Install).
  • Run the agent under lonca run, which gives the session isolated in a sandbox Lonca owns (Running agents).

Changes integrate without any build or tests​

No build or test command is set in [verification], so nothing checks that the code compiles: a file the grammar can not read waits for a person, whether it is a mistake or syntax newer than the grammar (Languages). Set them with lonca policy set; with verification.required = true a change can not land without them (Verification).

A change stays queued​

lonca status shows the queue. The daemon's worker takes the head of the queue (one change, or [queue] batch_size of them), and each check can take up to verification.timeout_seconds. If nothing moves, lonca queue wakes the worker; the daemon's output says what it is doing.

A change is conflicted or rejected​

lonca change <id> --evidence says which symbols conflicted or which check failed, with its log. The agent syncs, fixes and proposes again (Reviewing agents' work).

A session is unhooked, or never bound​

status shows unhooked when a call to lonca mcp came without the harness's hook event before it: a flag, a setting or a new version skipped the hooks. The session is tainted for good. Fix the harness's settings and start a new session. A session started without --harness stays unobserved on any machine (Running agents).

Touch ID, or a touch, on every command​

Each command opened a session of its own because none was live. lonca human login --ttl 8h opens one for the day (at most 24 hours).

lonca init refuses a file key​

A hardened repository requires presence, and a file key would lock itself out of everything after the first entry. Use lonca human keygen <name> --secure-enclave (Mac) or --security-key (a FIDO security key), or with neither, lonca init <repo> --without-presence (Profiles).

A security key does not sign​

ssh-keygen could not be run: a security key signs through OpenSSH 8.2 or later; install it, or name one with LONCA_SSH_KEYGEN (the ssh-keygen of macOS has no FIDO support built in; Homebrew's has). ssh-keygen did not sign: the key was not touched in time or is not plugged in. A denial bad_human_signature with a key that was touched: the key was made with no-touch-required, or for another application than ssh:lonca; make one with lonca human keygen --security-key.

The daemon will not start​

  • Socket path too long. Unix socket paths are limited to about 100 bytes. Use a shorter LONCA_HOME, or set LONCA_SOCKET.
  • No sandbox on a hardened install: install bubblewrap, or start it with --allow-unsandboxed and accept that verification is unsandboxed.
  • A repository does not verify: the daemon refuses to open a log whose chain or key switches do not replay, and says which. Audit it with lonca-audit verify; restore it from a backup or a pushed remote (Recovery).