shelf Docs
On this page

How errors look

Without --json, on stderr:

terminal
shelf return pdf-tools
error: The project copy of "pdf-tools" has local edits
hint: Keep them with `shelf promote pdf-tools` or `shelf detach pdf-tools`, or discard them with --force

With --json, one line on stdout:

json
{"schemaVersion":1,"ok":false,"error":{"code":"NOT_BORROWED","message":"\"nope\" is not borrowed by storefront","hint":"Run `shelf borrow nope` first"}}

hint is null when there is nothing more specific to say than the message.

Codes

CodeExit codeMeaning
INTERNAL1Anything that is not a ShelfError: a bug or an unexpected I/O error. The message says what failed.
INVALID_ARGUMENT2A missing or malformed argument, option or config value, or a request that does not apply (for example promoting a copy with no local edits).
INVALID_SKILL2A SKILL.md is missing, has no or invalid YAML frontmatter, or breaks a rule of the Agent Skills spec (name, description).
NOT_INITIALIZED3The current directory is not in a shelf project. Run shelf init in the project root.
SKILL_NOT_FOUND4No skill, set or source entry by that name.
NOT_BORROWED4The skill is in the library, but this project has not borrowed it.
SKILL_EXISTS5A skill or set with that name already exists.
CONFLICT5The operation would overwrite or orphan something: files shelf does not manage, a newer library revision, copies edited differently, or loans in other projects.
LOCAL_CHANGES6The project copy has local edits that the operation would discard. Promote or detach them first, or pass --force.
LOAN_LIMIT7The requested loan length or due date is beyond maxLoanDays.
NOT_ALLOWED8The actor may not do this, for example an agent importing from a remote source while allowAgentImports is off.

INTERNAL (exit 1) is not a shelf error code but what the CLI reports for anything unexpected: a bug, a full disk. The message is the underlying error; text output adds a stack trace. Please report reproducible ones.

What to do

INVALID_ARGUMENT

An argument, option or file shelf reads is not acceptable. Read the message; it names the value.

CauseFix
Unknown command, missing argumentshelf <command> --help
An invalid skill or set name1 to 64 lowercase letters, digits and single hyphens
A number option (--days, --limit, --depth, --port) that isn't a positive integerPass a whole number above 0
A due expression that isn't +Nd, -Nd, +Nw, -Nw or YYYY-MM-DDUse one of those
A revision that is too short, ambiguous or unknownAt least 6 hex characters; shelf log <name> lists them
shelf promote on a copy without editsNothing to promote
shelf pull on a skill without a sourceLink it first with shelf add <source> --yes
shelf add: no SKILL.md, several skills without --skill/--all, a failed cloneFollow the hint
shelf targets: a path outside the project, or no targets leftUse a harness id or a project-relative directory
shelf adopt on a path inside the shelf homeIt is already managed
shelf new with a description over 1024 charactersShorten it; nothing was created
An invalid config.jsonFix the file; the message names the key

INVALID_SKILL

A SKILL.md isn't a valid skill: no frontmatter, invalid YAML, a name that doesn't match its directory, a missing or overlong description. It comes from commands that read a skill directory you point at (adopt, add, promote, restore, rename). Fix the frontmatter; shelf lint and Writing skills list the rules.

NOT_INITIALIZED

The working directory isn't inside a shelf project, and the command needs one (borrow, renew, return, sync, targets, suggest, …). Run the command inside the project, or shelf init in its root if it should start using shelf. Agents shouldn't run init unless asked.

SKILL_NOT_FOUND

No skill (or set) by that name. shelf catalog lists skills, shelf set list lists sets. Archived skills and library directories that aren't valid skills (see shelf doctor) count as not found, except to shelf lint, which reports why they don't load. shelf add --skill uses it for a name the source doesn't have; the hint lists what it has.

NOT_BORROWED

The project doesn't borrow that skill. shelf status lists its loans; shelf borrow <name> borrows it. shelf diff uses it when borrowed or project is asked for outside a project that borrows the skill.

SKILL_EXISTS

The name is taken: a library directory with that name exists (new, rename, duplicate), an archived skill had that name (new, rename, duplicate, add), or the skill is already linked to a source (add; use shelf pull). Choose another name, or restore the archived skill by moving it back from ~/.shelf/archive/.

CONFLICT

The operation would clash with state shelf doesn't own or can't reconcile on its own.

CauseFix
borrow: a target already has an unmanaged directory with the skill's nameAdopt it (shelf adopt <path>), or move it away
promote: the library changed since the project borrowed (diverged)Review with shelf diff, then --force to replace the library's revision
promote: the copies in different targets were edited differentlyMake them identical
promote or diff --to project: copies are missingshelf sync
pull: the library copy was edited since the last import--force to replace your edits with the source
rename, archive: the skill is borrowedReturn it from each borrowing project first
The lockfile isn't valid JSON or doesn't match its schemaRestore it from version control; never edit it by hand. See Lockfile
A revision's snapshot is missing from the object storeshelf doctor
ui --port: the port is in useIf it is another shelf ui, open the URL in the hint; otherwise pick another --port, or leave it out for a free one

LOCAL_CHANGES

A project copy has local edits that the operation would discard: return, update <name>, or targets --remove. Keep the edits with shelf promote <name> (to the library) or shelf detach <name> (in the project), or discard them with --force.

LOAN_LIMIT

The due date would be more than maxLoanDays (90 by default) from now: borrow --days, renew, due or loan-days. The hint gives the latest allowed date or number of days. Use a shorter period, or raise maxLoanDays in the config. For a skill the project always needs, shelf keep is the alternative.

NOT_ALLOWED

An agent tried to import a skill from a git source (shelf add --yes of a new skill, or shelf pull --yes) while allowAgentImports is false. The agent should show you the review and the exact command, for you to run. See Importing skills.

Usage errors without --json

Without --json, an unknown command or a missing argument prints the command's help followed by the problem, and exits with code 2 (as with --json):

terminal
shelf new nod
…
Missing required argument: --description