Output and exit codes

This page is the contract for scripts, CI jobs, and AI agents that run skc. See Use SkillCatalog in scripts and CI.

Where output goes

skc writes results to standard output and problems to standard error.

OutputStream
Success messages, reports, and listsStandard output
The JSON envelope of a command that succeededStandard output
Every error, including JSON error envelopesStandard error
What a failing check found: drift from skc deliver --check, pending changes from skc update --check, findings that fail skc validateStandard error
A warning about a command that still succeeded, such as Warning: delivery after mutation failed.Standard output, after the success message
A warning that does not come from a failed step: a skill skc skill list could not read, recovery files that skc sync found, no AI tool turned on after skc profile add or skc install, or a metrics address that skc catalog add did not saveStandard error
The review of uncommitted changes, the commit message prompt, and the cancel notice of skc syncStandard error
The prompts of skc initStandard output
Progress from the AI provider during skc skill score and skc skill improveStandard error, unless you pass --json or --quiet
Diagnostic logsLog files only. See Logs.

In text mode, most errors start with a line Error: <outcome>, followed by the message and a Hint: line with the next step. In scripts, use the exit code or JSON output instead of this text.

skc skill list, skc sync, skc profile add, skc install, and skc catalog add print their warnings in text mode only.

--quiet hides the success summary of skc sync, skc deliver, skc install, skc uninstall, skc update, skc init, skc validate, skc status, skc catalog add, and skc catalog remove. For skc catalog add, that includes the line that names the catalog's metrics address. The warning about an address it did not save still prints.

JSON envelope

With --json, a command prints one JSON object on one line: to standard output when it succeeds, and to standard error when it fails. The object always has the same six keys, in no fixed order. A few commands print raw JSON instead. See Raw output.

skc catalog policy show acme-skills --json
{"command":"catalog.policy.show","data":{"catalog_id":"acme-skills","sync_policy":{"mode":"direct"}},"error":null,"exit_code":0,"outcome":"catalog-policy","status":"ok"}

A command that fails fills error:

skc sync acme-skill --json
{"command":"sync","data":null,"error":{"details":null,"message":"catalog(s) not found: acme-skill","recovery_hint":"Choose registered catalog ids from `skc status` and rerun `skc sync`."},"exit_code":17,"outcome":"catalog-not-found","status":"error"}
KeyValue
commandThe command with dots between its words, such as sync, catalog.add, or scoring.providers.list.
status"ok" or "error".
outcomeA stable name for what happened, such as sync-complete or dirty-tree. See Exit codes.
exit_codeThe process exit code. It is 0 when status is "ok".
dataThe result, or null. A failed skc sync puts its per-catalog report in data.result, and skc deliver --check puts the files it found in data.drift.
errornull on success. On failure, an object with message (text), recovery_hint (text or null), and details (an object or null). For dirty-tree, details lists the changed files of each catalog. When skc install or skc update registered a catalog before it failed, details.registered_catalogs lists it.

A command with two names reports the one you ran: skc install reports install, and skc profile install reports profile.install. The same holds for uninstall and init. skc score-history reports skill.score-history.

skc proposal show, skc proposal discard, and skc hook run print some of their errors as plain text. With --json, those errors arrive with outcome set to internal-error, the command's own exit code, and the plain text in error.message. The tables below mark these outcome names "text only".

Raw output

These commands print their result without the envelope, even with --json:

CommandWhat it prints to standard output
skc help-jsonThe full command tree as JSON
skc completions <shell>A completion script for bash, zsh, fish, or powershell
skc skill scoreThe skill's score history as JSON, with the new run's id in new_run_id
skc skill score-history, skc score-historyThe skill's score history as JSON

Their errors still go to standard error. skc skill score, skc skill score-history, and skc skill improve print scoring failures as a JSON envelope even without --json. Problems with choosing the catalog print as text unless you pass --json.

Parse errors

When skc cannot parse its arguments, it prints the problem to standard error and exits 2. That covers an unknown command or flag, a missing or invalid value, and two flags that cannot be combined. Running skc with no command prints the help to standard error and also exits 2. --help and --version print to standard output and exit 0.

If the arguments include --json, the error is a JSON envelope on standard error, with command set to skc and outcome set to cli-parse-error:

skc settings enable vim --json
{"command":"skc","data":null,"error":{"details":{"parser_error_kind":"InvalidValue","rendered":"error: invalid value 'vim' for '<TARGET_ID>'\n  [possible values: claude-code, cursor, codex]\n\nFor more information, try '--help'."},"message":"error: invalid value 'vim' for '<TARGET_ID>'","recovery_hint":"Run `skc --help` for usage or `skc help-json` for the machine-readable command tree."},"exit_code":2,"outcome":"cli-parse-error","status":"error"}

Exit codes

0 means the command succeeded. Any other code means it failed or found a problem. The same number means different things in different commands. Read a code together with the command that returned it, or branch on outcome in JSON output.

Rows that ask you to run skc validate mean that a profile file (profile.yml) or a delivery record (delivery-manifest.json) in the SkillCatalog folder is damaged. See Report a problem.

Codes every command can return

ExitOutcomeWhat happened
0Depends on the commandThe command succeeded.
2cli-parse-error (with --json)The arguments could not be parsed. See Parse errors.
70internal-errorSkillCatalog could not finish, for example because it could not read its own files or write its output. The message names the cause.

skc completions and skc help-json return only these codes. When the reader closes the pipe early, as in skc help-json | head, skc help-json stops quietly and exits 0. Any other failure to write its output exits 70.

Codes shared by install, update, uninstall, and deliver

These codes mean the same in each command named in the row. The tables for those commands leave them out.

ExitOutcomeCommandsWhat happened
10checkout-path-not-canonicalinstall, update, uninstallThe current folder cannot be resolved to a real path.
11manifest-malformedinstall, update, deliverThe team or local manifest cannot be read or breaks a rule.
12manifest-path-not-canonicalinstall, update, deliverThe manifest's path cannot be resolved to a real file.
19manifest-missinginstall, update, deliverThe team manifest is missing: in the current folder, or for skc deliver, in a project profile's checkout.
46manifest-changedinstall, update, deliverThe team manifest changed during the run, before SkillCatalog wrote anything. Nothing changed; run the command again.
47changed-after-<effect>install, update, deliverThe team manifest changed after SkillCatalog had written something. The JSON data names what was written (effect, commitment, locators), and error.recovery_hint says how to reconcile it.
47manifest-write-failedinstall, updateSkillCatalog cannot tell whether a failed write changed your local manifest.

The <effect> part is one of local-yaml, local-privacy, installed-clear, profile-save, catalog, catalog-refresh, delivery-target, or delivery-manifest, and names what SkillCatalog had written.

skc sync

ExitOutcomeWhat happened
0sync-completeEvery selected catalog synced. Delivery ran, unless you passed --no-deliver.
0no-catalogsNo catalogs are registered.
0NoneYou left a commit message empty at the prompt, or input ended. Sync prints Sync cancelled; nothing was synced. and changes nothing.
10empty-message--message is empty.
11commit-message-too-longThe message is over 1,000 bytes after trimming, from --message or the prompt.
12missing-configGit's user.name or user.email is not set, and sync needs to commit.
17catalog-not-foundA catalog id you passed is not registered.
25delivery-failedThe catalogs synced, but delivery reported a problem or stopped with an error. See skc deliver for what counts as a problem.
25proposal-reconciliation-blockedThe catalogs synced, but SkillCatalog could not lock, read, or save the proposal records of a review-branch catalog, so delivery did not run.
33dirty-treeA catalog has uncommitted changes, you passed no --message, and standard input or standard output is not a terminal. The message names which one.
34another-sync-runningAnother process holds the lock of a catalog: a Git operation in its clone, or a sync or save by SkillCatalog. The message names the busy catalog.
41sync-partialSome catalogs synced and others failed.
44sync-all-failedEvery selected catalog failed.

A failed catalog stops delivery for the whole run. For example, a catalog fails when:

  • its Git host cannot be reached, or refuses the push. For a refused push, the catalog's report.push.message in JSON holds the host's reason.
  • its pre-commit check refuses the commit.
  • a pull conflicts. The message names every file that Git could not merge.
  • its clone's own Git data is missing or damaged, so Git would use another repository. Nothing is committed or pushed.

A review-branch catalog also fails when:

  • an edit cannot be merged onto the proposal already waiting for that item. The edit stays in the clone, uncommitted.
  • the Git host refuses a proposal push. Edits from this run go back into the clone, uncommitted. Local commits on the primary branch stay there, and the next sync tries again.
  • local commits on the primary branch conflict with new commits on origin. The message prints a git -C '<clone>' reset --soft <commit> command that stages only those local commits.
  • its clone has an unfinished merge, rebase, or cherry-pick.

See Sync refuses one catalog and Local commits conflict with the Git host.

Sync delivers only when every selected catalog committed, pulled, and pushed. When that delivery reports a problem, skc sync exits 25, as skc deliver does, and data.result.delivery holds the report in JSON. Edited files that delivery kept are not a problem, so sync still exits 0 for them. With --json, when some reported files already match the catalog version, error.recovery_hint names skc deliver <profile-id> --adopt-matching.

When delivery stops with an error, data.result.delivery_error holds the outcome and exit code that skc deliver gives for that error. For example, when no profile could be delivered because a proposal's state is unknown, that is delivery-blocked-by-remote-status-unknown and 45.

In text mode, sync ends with one warning line for each synced catalog that has recovery files from syncs that did not finish. The warning does not change the exit code. See Recover unpublished changes.

skc deliver

ExitOutcomeWhat happened
0delivery-completeEvery selected profile and skill was delivered, no file failed, and no two catalogs delivered the same slug. Edited files it kept are listed. With --check: no delivered file changed.
0delivery-dry-run-complete--dry-run computed the changes without writing. It found nothing to withhold and no same-slug conflict. Existing files that SkillCatalog did not write are counted on a Blocked: line, with the command that takes over the ones that match.
10user-input-invalidThe profile id is not valid, or no profile has it.
20install-path-conflictTwo profiles would write the same file.
25delivery-failedDelivery finished with a problem, and data.delivery lists each one: a file it could not write, a file SkillCatalog did not write at a delivery path, a withheld profile or skill, or two skills from different catalogs with the same slug. A dry run exits 25 when its plan withholds a profile or skill, or has a same-slug conflict, and lists them in data.preview.
26delivery-check-drift--check found delivered files that were edited, deleted, or cannot be read, or a checkout or delivery folder that cannot be found.
28delivery-manifest-malformed, delivery-manifest-unreadableA profile's delivery record (delivery-manifest.json) is damaged. The hint says to remove it and rebuild it with skc deliver <profile-id> --adopt-matching.
43delivery-io-errorDelivery could not read or write what it needed, for example because a skill folder holds a file over 10 MiB, such as an old SCORE.json repair backup, or a special file, or because Git ignores a skill's SKILL.md.
43bound-catalog-clone-missingA profile uses a catalog that has no registered, readable clone.
44delivery-composition-gapA stack or bundle includes a skill that refers to a skill outside it.
45delivery-blocked-by-remote-status-unknownA proposal on a review-branch catalog has an unknown state. See Delivery while proposals are pending.
45delivery-blocked-by-metadata-failureA proposal record of a review-branch catalog cannot be read. Nothing is delivered.
47delivery-manifest-save-failed-after-effectFiles were written, but the delivery record could not be saved.
10, 24, 43local-child-entry-divergence and local-manifest-migration-repair (10), home-profile-parent-metadata (24), profile-parent-path-invalid and profile-catalog-id-undeclared (43)A profile file (profile.yml) is damaged, or points at a team manifest that cannot be used. Run skc validate and include its output when you report the problem.

skc deliver <profile-id> for a project profile whose checkout, or --target-dir folder, cannot be found exits 43 with profile-parent-path-invalid. The hint says to mount the folder. For a missing checkout, it also names skc profile delete <profile-id>; for a missing --target-dir folder, skc install --target-dir . run in the checkout. See A profile's folder cannot be found.

Partial delivery

When a profile or a skill cannot be delivered for one of the reasons in the table below, skc deliver withholds it, delivers the rest, and exits 25. A withheld skill keeps the files it delivered earlier. When no profile with entries could be delivered, the run instead exits with the error of the first withheld profile, such as bound-catalog-clone-missing (43), delivery-composition-gap (44), or delivery-blocked-by-remote-status-unknown (45). A profile with no entries does not count.

Only the reasons in the table withhold part of a run. Any other error stops the whole run for every profile, for example a special file or a file over 10 MiB in a skill folder, a Git-ignored SKILL.md, or an unreadable proposal record.

Each problem is a row in data.delivery.failures (data.preview.failures for a dry run), with the profile_id, the install_path, the reason, and the remedies that apply:

reasonWhat happened
unmanaged_target_existsA file that SkillCatalog did not write is at a delivery path. Delivery leaves it. When it matches the catalog version, remedies includes adopt, and skc deliver --adopt-matching takes it over.
broken_entryAn entry cannot be resolved, for example a misspelled slug or a catalog removed with --force. The whole profile is withheld.
checkout_missingA project profile's checkout, or its --target-dir folder, cannot be found. The whole profile is withheld.
symlink_in_skillThe skill's folder in the catalog holds a symbolic link. That skill is withheld.
blocked_remote_status_unknownThe skill comes from a review-branch catalog with a proposal whose state is unknown. That skill is withheld.
target_inspection_failed, unsafe_parent_path, directory_create_failed, file_write_failed, file_finalize_failed, removal_failedDelivery could not check, write, or remove one file.

--adopt-matching takes over only files that are exactly what delivery would write. It never overwrites a file with different content. When some rows can be taken over, the text output and the JSON error.recovery_hint of skc deliver, skc install, skc update, and skc sync name the command.

skc install and skc profile install

ExitOutcomeWhat happened
0installed-freshThe project profile was created and delivered.
0installed-idempotentThe project profile already existed. SkillCatalog registered any declared catalog that this machine lacked, pulled the catalogs, and delivered the profile again.
13manifest-reference-missingAn entry names a skill, stack, or bundle that the catalog does not have.
14manifest-reference-wrong-kindAn entry's kind does not match the item, for example stack for a skill.
16catalog-source-invalidA catalog source is not a supported remote Git URL.
16missing-git-identityA declared catalog repository is empty, and committing its starter files needs a Git name and email.
20install-path-conflictAnother profile writes the same files.
21profile-id-conflictAnother checkout already has a project profile with this id. The hint depends on whether that checkout can still be found.
23catalog-clone-unreadableA catalog clone cannot be read.
24profile-write-failedThe profile could not be saved.
25delivery-failedThe profile was saved, but delivery reported a problem or stopped with an error. See skc deliver for what counts as a problem.
26install-url-mismatchThe manifest gives a catalog a different source than the one registered.
27catalog-integrityA catalog clone fails its integrity checks.
28install-intrinsic-id-mismatchThe source's catalog.yaml has a different id than the manifest's key.
29checkout-directory-conflictMore than one profile claims this checkout.
30target-directory-invalidThe --target-dir folder does not exist or cannot be used.
40catalog-clone-failedA declared catalog could not be cloned.
42catalog-refresh-failedA registered catalog could not be pulled before delivery.
11, 24profile-catalog-id-undeclared (11), local-child-entry-divergence and local-manifest-migration-repair (24)A profile file (profile.yml) is damaged. Run skc validate and include its output when you report the problem.

skc install and skc update clone and register each catalog that the manifests declare and this machine has not registered. For each one they print Registered catalog '<catalog-id>' from <source> (declared in <manifest path>). on standard output, also with --quiet, and also when the run fails afterwards. When the catalog names a metrics address, the next line names it too.

The JSON output of a successful skc install, or of skc update without --check, always has data.registered_catalogs. It lists these catalogs and is empty when there are none. When the run fails after registering a catalog, error.details.registered_catalogs lists it instead. Each entry has catalog_id and source, and metrics_url when the catalog names a metrics address.

skc update

ExitOutcomeWhat happened
0project-updatedSkillCatalog registered any declared catalog that this machine lacked, pulled the catalogs, and delivered the project profile.
0up-to-date--check: delivery would change nothing.
15missing-install-stateNo project profile is installed for this checkout. Run skc install first.
16installed-profile-missingA profile claims this checkout, but its record is missing.
17missing-registered-catalog-id--check: a catalog the manifests declare is not registered on this machine. Run skc update to register and clone it.
17registered-catalog-source-mismatchThe registered catalog uses a different source than the manifest.
18manifest-profile-mismatchThe manifest declares a different profile id than the one installed for this checkout.
23registered-catalog-unreadableA registered catalog's clone cannot be read.
24update-needed--check: delivery would create, update, or remove files.
24delivery-blocked--check: edited files, or files SkillCatalog did not write, block delivery. data.needs_update is false.
25delivery-failedDelivery reported a problem or stopped with an error. See skc deliver for what counts as a problem. With --check: delivery would withhold a skill or the profile. This wins over 24.
27catalog-integrityA catalog clone fails its integrity checks.
29checkout-conflictMore than one profile claims this checkout.
42catalog-refresh-failedA catalog could not be pulled, for example because its Git host cannot be reached.
30local-child-entry-divergence, local-manifest-migration-repairThe project profile's file (profile.yml) is damaged. Run skc validate and include its output when you report the problem.

skc update --check does not pull catalogs, so it never returns 42.

When skc update cannot register a declared catalog, it reports catalog-refresh-failed (42). A declared id that differs from the id of the cloned catalog reports manifest-malformed (11) instead.

skc init and skc profile init

ExitOutcomeWhat happened
0manifest-writtenThe team manifest was written.
10user-input-invalidA flag value is invalid, or a catalog id is not registered and has no --source. It also means required input is missing, because standard input is not a terminal, --json never prompts, or input ended early. Without a terminal, the command fails at once and names the missing flags.
11manifest-malformedThe values would make an invalid manifest.
11manifest-reserved-idThe profile id is home.
18manifest-existsThe folder already has a team manifest.
27manifest-write-failedThe manifest file could not be written.

skc uninstall and skc profile uninstall

ExitOutcomeWhat happened
0uninstalledThe project profile and its delivered files were removed. Edited files are kept and listed.
15no-profile-at-checkoutNo project profile is installed for this checkout.
25delivery-failedSome delivered files could not be removed, or SkillCatalog could not record the edited files it kept. The profile stays installed, so you can run the command again.
29checkout-directory-conflictMore than one profile claims this checkout.

skc validate and skc hook run

ExitOutcomeWhat happened
0validate-reportNo findings, only info findings, or only warnings with --warnings-ok.
30validate-reportErrors, or warnings without --warnings-ok, and no finding comes from the team manifest check. Drift is an error.
31validate-reportThe same, and at least one finding comes from the team manifest check.
64hook-protocol (text only)skc hook run received a --protocol number other than 1. A value that is not a number is a parse error.

skc hook run, which a catalog's pre-commit hook calls, runs skc validate --path <clone> --warnings-ok --no-drift and returns the same codes. Edited delivered copies therefore never block a commit.

skc validate --profiles reports profile-slug-conflict, an error, when two entries of one profile deliver different skills with the same slug.

skc status

ExitOutcomeWhat happened
0status-reportThe report printed. Drift is listed in it and does not change the exit code.
32status-inconsistent-stateProfile files, settings, or registered catalogs have errors or warnings, or two entries of one profile deliver different skills with the same slug. Run skc validate for details.

skc catalog

CommandExitOutcomeWhat happened
add0catalog-added, catalog-already-registeredThe catalog is registered and cloned. JSON output holds the metrics address the added catalog names in data.metrics_url, and the warning about a --metrics-url address that was not saved in data.metrics_url_warning. Each is null otherwise; for catalog-already-registered, data.metrics_url is always null and no line names the catalog's metrics address, because nothing was added.
add16catalog-source-invalidThe source is not a supported remote Git URL, or it conflicts with a registered catalog.
add16missing-git-identityThe repository is empty, and committing its starter files needs a Git name and email.
add23catalog-clone-unreadableThe clone cannot be used, for example because the repository has commits but no catalog.yaml.
add40catalog-clone-failedCloning failed: a wrong URL, no access, or a Git host that cannot be reached.
remove0catalog-removedThe catalog is unregistered and its clone deleted, including changes not yet synced, unless you passed --keep-clone.
remove17catalog-not-foundNo catalog has that id.
remove32catalog-remove-in-useProfiles use the catalog: through their own entries, a checkout's local manifest, or a team manifest. The hint lists one skc profile remove command per entry. --force removes it anyway, and the profiles with entries from it are not delivered until you remove those entries.
remove, policy set32catalog_read_onlyThe Essentials catalog cannot be removed or changed.
remove33catalog-removed-clone-cleanup-pendingThe catalog is unregistered, but its clone could not be deleted. Run the command again to retry.
list0catalogs-listedThe registered catalogs printed.
stats0catalog-stats-shownThe counts printed.
stats, changes17catalog-not-foundNo catalog has that id.
stats, changes23catalog-clone-unreadableThe catalog's clone cannot be read.
list, stats16, 23, 40catalog-source-invalid, catalog-clone-unreadable, catalog-clone-failedThe registration or clone of a catalog is broken. The message names it.
changes0catalog-changes-listedThe uncommitted changes printed.
changes70catalog-read-failedThe changes could not be read.
policy show, policy set0catalog-policyThe sync policy printed, after any change.
policy show, policy set10catalog-policyThe branch values are invalid, for example --review equals --primary.
policy show, policy set17catalog-not-foundNo catalog has that id.

skc catalog add checks --metrics-url while it reads its arguments, so an invalid address is a parse error, and nothing is cloned.

skc profile

CommandExitOutcomeWhat happened
All0profiles-listed, profile-shown, profile-created, profile-deleted, profile-entry-added, profile-entry-removed, profile-reorderedThe command succeeded.
show, create, delete, add, remove, reorder10user-input-invalid, profile-not-found, duplicate-priority-entry, entry-catalog-unregisteredAn argument is invalid, the profile does not exist, the entry is already in the profile, or its catalog is not registered.
add10skill-not-found, stack-not-found, bundle-not-foundThe catalog has no item of that kind with that slug. When the slug exists as another kind, the message says so.
show --effective10effective-parent-invalidThe project profile's team manifest cannot be used.
create, add, remove, reorder23catalog-clone-unreadableA catalog's clone cannot be read.
create, delete, add, remove, reorder24profile-write-failedThe profile could not be saved or deleted.
create24profile-seeded-persistence-failedThe entries given with --entry could not be saved, so the profile was not created. When removing the partial profile also failed, the message says so.
add, remove, reorder24manifest-missing, manifest-malformed, manifest-path-not-canonical, manifest-changed, manifest-write-failedA project profile's team or local manifest is missing, invalid, changed during the run, or could not be written. The message names the file.
add, remove, reorder47changed-after-<effect>, manifest-write-failedAs for skc install. See Codes shared by install, update, uninstall, and deliver.
add, remove, reorder10, 24local-child-entry-divergence and local-manifest-migration-repair (10), home-profile-parent-metadata (24)A profile file (profile.yml) is damaged. Run skc validate and include its output when you report the problem.

skc profile add, remove, and reorder exit 0 when the profile changed, even if the delivery that follows fails. They print the warning after the success message, and JSON output holds it in data.delivery_warning. When no AI tool is turned on, skc profile add and skc install also print a warning on standard error that nothing was delivered.

skc settings

CommandExitOutcomeWhat happened
show, list0settings-shownThe settings printed.
enable, disable0delivery-target-enabled, delivery-target-disabledThe tool was turned on or off and delivery ran. A delivery problem prints a warning and does not change the exit code; JSON output holds it in data.delivery_warning.
telemetry0telemetry-settings-shownThe usage metrics switch and the catalogs with a metrics address printed, after any change. A catalog registry that cannot be read does not fail the command.
enable, disable10user-input-invalidThe settings change was rejected.
All70settings-unreadablesettings.toml cannot be read or parsed.

An unknown tool id is a parse error, and so is skc settings telemetry with both --enable and --disable.

With --json, skc settings telemetry returns data.enabled and data.metrics_catalogs. That is one {catalog_id, name, metrics_url} object for each catalog with a metrics address, or null when the registered catalogs cannot be read.

skc proposal

CommandExitOutcomeWhat happened
list0proposals-listedThe proposals printed.
show0proposal-shownThe proposal printed.
refresh0proposals-refreshedSkillCatalog checked each proposal on the Git host. One it could not reach is marked remote_status_unknown, and records it could not save are listed in data.errors.
discard0proposal-discardedThe record was discarded.
verify-clean0verifiedEvery review-branch clone passed.
verify-clean1invariants-violatedA review-branch clone failed a check, and data.catalogs lists each failure. The checks include that the clone is on its primary branch, and level with its local copy of origin/<primary>. The command does not fetch.
discard2not-applicable, already-discarded, refresh-failed, discard-not-applicable (text only)The catalog does not use proposals, the proposal is already discarded, or its remote state could not be checked. discard-not-applicable: its state does not allow discarding, so run skc sync instead.
show, discard3not-found (text only)No active proposal has that id.
All70internal-errorAmong other causes, a --catalog-id that is not registered.

skc skill, skc stack, and skc bundle: list and show

ExitOutcomeWhat happened
0skills-listed, skill-shown, stacks-listed, stack-shown, bundles-listed, bundle-shownThe command succeeded.
10user-input-invalidThe catalog id arguments conflict or are missing.
10skill-not-found, stack-not-found, bundle-not-foundThe catalog has no item with that slug.
17catalog-not-foundNo catalog has that id.
23catalog-clone-unreadable, catalog-read-failedThe catalog's clone, or an item the command reads, cannot be read.

skc skill list leaves out a skill it cannot read, such as one whose front matter lacks description, and still exits 0. Text output prints one warning line on standard error for each such skill, also with --quiet. JSON output lists them in invalid_items, each with slug, path, and error. skc validate still reports the skill. See A skill is missing from the list.

Scoring and improvement commands

These codes apply to skc skill score, skc skill score-history, skc score-history, skc skill improve, and skc skill publish-accepted.

ExitOutcomeWhat happened
0Raw JSON, improvement-preview-ready, reviewed-improvement-applied, improvement-generated-and-applied, accepted-improvement-publishedThe command succeeded. skc skill score and skc skill score-history print raw JSON. See Raw output.
32Any other outcomeScoring, improving, or publishing failed. outcome names the reason, for example zero_opted_in_providers_configured (no AI provider is turned on), no_current_scoring_baseline (score the skill before improving it), catalog-not-found, or publish-delivery-blocked-by-unrelated-changes. When SCORE.json is over 10 MiB, the hint names skc skill score-history <slug> --catalog-id <catalog-id> --repair.
33scoring_run_in_progressAnother scoring run of the same skill is active.
41score-finalization-conflictskc skill score could not save the score because the catalog changed during the run.

skc scoring providers

ExitOutcomeWhat happened
0scoring-providers-listed, scoring-provider-enabled, scoring-provider-disabled, scoring-provider-model-set, scoring-provider-effort-set, scoring-provider-model-cleared, scoring-provider-effort-clearedThe command succeeded.
2unknown-provider, invalid-effortThe provider id is unknown, or the provider does not accept that effort value.
10empty-valueset-model or set-effort received an empty value. Use clear-model or clear-effort instead.
70settings-unreadable, settings-unwritablesettings.toml cannot be read or written.