Token expired or out of scope

The TVO-TOKEN family, including mid-session expiry and what cannot be renewed.

Written By Dustin

Last updated 19 minutes ago

TVO-TOKEN-* covers validity, scope, expiry, revocation, and delegation. Most of it exits class 13 (permission), with two deliberate exceptions noted below that exit 11 (key material) — so branch on the code, not the exit.

Expired mid-session

TVO-TOKEN-002, and the common case for a long-running agent. The token reached its expires_at; there is no grace period.

tovio agent show <token-id>tovio agent renew <token-id> --expires-in <hours>

--expires-in defaults to 24 hours. Renew rather than issuing a new token, so the provenance chain stays continuous — and for long tasks renew before expiry rather than catching the failure.

Renewal itself refused

TVO-TOKEN-007. Renewal is a deliberate re-issue of a live root token, so three things cannot be renewed: a revoked token, a delegated sub-token, and a token with an empty validity window. If a sub-agent’s token lapsed, the fix is for its issuer to mint a fresh delegation — not to renew the leaf.

Out of scope

TVO-TOKEN-001 for a path outside the token’s path scope, rejected before any policy is read; TVO-TOKEN-004 when the path is in scope but the operation is not in allowed_ops (or sits in denied_ops). Scope is checked before anything is sealed, so nothing is half-written.

tovio agent show <token-id>

An MCP client can call effective_scope to report what it actually holds — useful when an agent claims it cannot do something. Fix by reissuing with the scope the task genuinely needs. Do not widen a token to make one error go away.

Revoked

TVO-TOKEN-003. Revocation cascades: a sub-token stops when any token in its delegation chain is revoked. Issue a fresh token.

The ones that look like bugs and are not

  • TVO-TOKEN-006 — no token with that id in this repository’s local index. Usually a typo, or a token minted in a different clone.
  • TVO-TOKEN-008 — you are in a Simple repository, which has no cryptographic identity. Capability tokens must be signed by a human issuer, so they need a repo initialized in team or agentic mode. Exits 11, not 13 — what is missing is key material, not permission.
  • TVO-TOKEN-009 — the token would grant more than the issuing human holds. A token can never exceed its issuer; widen the human’s access first, or narrow the token.
  • TVO-TOKEN-005 — a sub-token asked for a scope not provably contained in its parent. Delegation narrows monotonically and never widens.
  • TVO-TOKEN-010 — the commit reached the seal stage for a clearance-gated path and the token carries no clearance. Clearance is separate from path scope and must be granted explicitly.

A CI runner cannot use its session bundle

TVO-TOKEN-011 — and despite the TOKEN area this is about the bundle, not the token’s scope. It exits 11. The bundle is absent on one side of its required path pair, empty, oversized, non-canonical, expired, for another repository, encrypted under a different passphrase, tampered with, or does not bind its agent key to a current registration and valid capability chain.

One code deliberately covers load, decrypt, and verify together, so an unauthenticated caller cannot use the detail to probe. Re-export the bundle and make sure the runner has both mounted files — the bundle and its passphrase — and the environment variables pointing at them.

tovio agent session export <token-id> <bundle> --passphrase-file <file>

Delegated tokens and reconnect

An ephemeral delegated token whose ancestors were never persisted cannot be re-established on reconnect — the chain has to be verifiable end to end. Reconnect through a persisted chain rather than trying to renew the leaf.

Reporting it

The code and whether the token was a root or a delegated sub-token. Never the token id, never its bytes, never TOVIO_TOKEN, and never a session bundle or its passphrase file.