SkillHub

Common errors

Exit-code-driven troubleshooting — auth failures, ambiguous names, copy fallback, offline sync, and orphaned skills.

Every command exits with a code that tells you what class of problem you hit, and --json failures return a structured error. This page maps the common situations to their cause and fix.

Exit codes at a glance

CodeClassTypical cause
0OKSuccess.
1User / validationBad input, ambiguous ref, invalid arguments.
2AuthNot logged in, or not authorized for the action.
3NetworkOffline, transport failure, retry later.
4Integrity / scanBlocking scan finding, or a content-hash mismatch.

With --json, a failure returns { ok: false, error: { code, message, details? } } on stdout — read message first.

Not logged in (exit 2)

Publishing, or any registry action, requires authentication. If you see an auth error, confirm who you are and log in:

skillhub whoami
skillhub login

In CI, the browser login flow can't run. Use a token instead — either login --token or the token environment variable. See API tokens.

Ambiguous short name (exit 1)

A bare skill name has to resolve to exactly one skill across your configured registries. If the same name exists in more than one, the command fails as ambiguous. Fix it by using the fully qualified ref:

skillhub install @studio/design-systems/tokens-workflow

Skills install once into a canonical store and fan out to each agent by symlink. On platforms without symlink support, SkillHub automatically falls back to copying and prints a notice — nothing fails. You can also opt into copying everywhere with --copy.

Copied skills show up in skillhub list with copyMode: true. This is expected behavior, not an error.

Offline sync — tolerated or exit 3

skillhub sync normally uses the network to resolve your subscription set. Run it offline and the outcome depends on what's already on disk:

  • If the lockfile is already satisfied on disk, sync warns that it's offline and exits 0 — there's nothing to reconcile, so being offline is tolerated.
  • If the lockfile cannot be reconciled offline — a resolve is genuinely needed — sync changes nothing rather than guessing and exits 3. Reconnect and run it again:
skillhub sync

In CI, sync --frozen fails with exit 1 if the lockfile would drift. That's by design — it tells you the committed lockfile is out of date, not that anything is broken.

Orphaned skills after revoked access

If a registry is deleted, or your access to it is revoked, its skills stay on disk but are marked orphaned in skillhub list. They're no longer backed by a reachable subscription. Clear them out with a pruning sync:

skillhub sync --prune

Deletion always requires --prune — a plain skillhub sync keeps orphaned skills on disk and only warns, so nothing disappears from under you by accident.

A skill package carries regular files and directories only, so skillhub validate and skillhub publish reject a directory containing a symlink with local.symlink — including one whose target sits inside the skill. The same applies to a path carrying control characters or a backslash (local.unsafe_path).

Replace the link with the file it points at, or leave it out of the package. The reasoning is in Archive safety.

Skill too large to publish (exit 1)

Two size ceilings apply to a published package, and tripping either is a hard error, not a warning you can acknowledge:

  • 50 MiB across all files. skillhub validate catches this locally as local.too_large, before anything is packed.
  • 10 MiB for the packed tarball. The registry refuses an upload over that (gz-too-large).

Both usually mean the same thing: something is in the directory that shouldn't ship — a checked-in binary, a model file, a node_modules. Trim it and re-run:

skillhub validate

A tarball that expands to more than 100× its compressed size is rejected as ratio-exceeded even when it clears both ceilings. In practice that's one large generated or highly repetitive file; drop it rather than trying to compress around the limit.

Structural warnings block a publish (exit 1)

Two limits describe a package's shape rather than its safety, so they surface as warnings you can acknowledge:

FindingLimit
local.too_many_files400 entries
local.too_deep6 directory levels

skillhub validate reports them and still exits 0. skillhub publish asks you to confirm them — but a non-interactive session (--json, or no TTY) has nobody to ask, so unless the run carries --yes it fails with WARNINGS_UNACKNOWLEDGED and exit 1, listing what it found, before any network call. Acknowledge them up front instead:

skillhub publish --allow-warnings

Acknowledged warnings are recorded on the published version and returned in published[].warnings. --allow-warnings covers these two limits and nothing more — every other archive rule hard-fails.

Drift and integrity (exit 4)

Exit 4 also covers a content-hash mismatch — the bytes on disk don't match the version they claim to be. Run skillhub doctor to locate the drift and follow its fix:

skillhub doctor

A downloaded tarball that fails the archive gate stops at the same exit code with code BAD_ARCHIVE, before anything is extracted. With --json, the exact rule it broke is in error.details.archiveErrorCode — see Archive safety for what each class of code means.

Where to go next

On this page