Debugging & troubleshooting
Most issues come down to one of three things: the machine isn't connected, it hasn't synced a bundle yet, or the hook isn't wired correctly. This page maps the exact message you'll see to its fix. Start by running skillsvault status — it shows the connected org, the bundle version, and how long ago it synced.
Quick reference
| Symptom | Cause | Fix |
|---|---|---|
not configured — run skillsvault login | No credentials on this machine | skillsvault login (or skillsvault configure for CI) |
no bundle — run skillsvault sync | Connected but never synced | skillsvault sync |
REJECTED bundle: signature verification failed | Pinned org key no longer matches | Reconnect to re-pin: skillsvault login |
Gate exits 2 unexpectedly | Skill is banned or non-compliant | Check skillsvault status and your policies |
| Hook never blocks in Claude Code | Matcher wrong / not synced | Matcher must be "Skill"; run skillsvault sync |
HTTP 401 | Bad or missing agent key | Check the key in Settings → Agent keys |
HTTP 403 | Key used against another org | Use the key's own org slug |
no harnesses detected on this machine | pull found no known agent dirs | Pass --harness <h> or --dir <path> |
Connection & sync
not configured
The CLI keeps per-machine state under ~/.skillsvault. If it's missing you'll see not configured — run skillsvault login. Connect interactively with skillsvault login, or non-interactively (CI) with skillsvault configure --org <slug> --key <agent-key> --url <base>.
no bundle — run skillsvault sync
The gate decides from a locally-synced bundle. A freshly connected machine has none until you run skillsvault sync, which pulls and verifies it. Confirm with skillsvault status:
skillsvault status
# bundle v1750848000 · 4 skills · 3 policies
# synced 2m ago
REJECTED bundle: signature verification failed
On connect, the CLI pins your org's signing key and then refuses any bundle that doesn't verify against it. If the org's key was rotated, an old pin will reject the new bundle. Reconnect to re-pin the current key:
skillsvault login # re-pins the org's current signing key
skillsvault sync
The last-good bundle is kept on a rejected sync, so the gate keeps working on the previous policy until you re-pin.
Enforcement
Gate exits 2 when you didn't expect it
Exit 2 is a halt. It means the skill is banned, or it sits under a managed namespace without a valid current manifest (the "managed missing manifest" default). Inspect the synced bundle with skillsvault status and review the matching rule in Policies. To see the decision and reason directly:
skillsvault gate --skill acme/teamleader-crm-entry
# ⛔ HALT acme/teamleader-crm-entry
# policy: Teamleader retired
# Use acme/hubspot-crm-entry instead.
The Claude Code hook isn't blocking
Three things to check, in order:
- The matcher is
"Skill". Print the correct config withskillsvault install-hookand paste it into.claude/settings.json. See Harness coverage. - A bundle is synced. Run
skillsvault syncfirst — with no bundle the gate can't decide. - You're reading the right signal. In hook mode the gate always exits 0 and signals a block via
permissionDecision: "deny"in its JSON output — not via the exit code. That's by design; see The runtime gate.
Enforcement is cooperative
The gate stops the accidental run of a stale or banned skill. It does not stop a developer who removes the hook or sideloads a folder outside a managed namespace. If a banned skill still runs, confirm the hook is installed and the namespace is managed.
API errors
When using the REST API or skillsvault against a remote control plane:
401— the agent key is missing or unknown. Confirm theX-Skillsvault-Key(orAuthorization: Bearer) header and that the key still exists in Settings → Agent keys.403— the key is valid but you're calling a different org's path than the key belongs to. Use the key's own org slug.
Offline & staleness
The gate never needs the network to decide — it uses the last-good bundle on disk, so an offline laptop keeps enforcing. If that bundle is older than the org's staleness threshold, the gate escalates: a stale bundle can turn an allow into a warn or halt (it only ever becomes more restrictive). Reconnect and skillsvault sync to refresh.
Inspecting state
skillsvault status # org, bundle version, sync age
skillsvault status --json # machine-readable, for scripts
skillsvault detect # AI agents found, enforced vs distribution-only
skillsvault gate --skill <name> # dry-run a decision with full reason
Add --no-color (or set NO_COLOR=1 / TERM=dumb) when capturing output, so logs and pipes stay plain text.