Errors

Every error code and every reason under it, with its meaning, its action, whether a retry helps, what to do next, the file reasons, and the startup refusals.

Every domain error carries three stable tokens: a code, a reason one level more specific, and an action naming the caller’s next step. Every file entry inside an error carries its own reason token. Message text can change between releases; these tokens cannot, so branch on them rather than on prose.

The retryable field says whether repeating the same call can help, which is not always the same as what action tells you to do next. PUBLICATION_UNPROVEN, for example, is retryable but asks you to pull first. It is decided by the code, except for STORAGE_FAILURE and RECOVERY_FAILURE, which are retryable unless the reason is STORAGE_FULL, REQUEST_LIMIT, ACCESS_DENIED, or OBJECT_TOO_LARGE: those name a refusal that a retry cannot change.

The codes

Code Retryable Meaning
INVALID_REQUEST no Invalid input, or a state the operation refuses before any Git or S3 work.
CONTENT_CONFLICT no A three-tree merge conflict, or marker blocks already present. The visible directory holds the full merged result with markers.
STORAGE_INTEGRITY no Stored state failed validation: a corrupt pack, a pack that contradicts its descriptor, a missing object in the accepted history, or a cache that cannot be trusted.
STORAGE_FAILURE yes An object-store operation failed without a known accepted result, or the store refused it. Not retryable for four refusal reasons, below.
REMOTE_BUSY yes The conditional write lost the configured retry bound. Visible files are preserved for another attempt.
RECOVERY_FAILURE yes An unexpected failure after local mutation started, or the recovery of an earlier one. The generic recovery path ran, and the error carries its report.

INCOMPATIBLE_STORE is a startup diagnostic and never appears in a tool result; it is covered at the end of this page.

Reasons, by code

The guard behind DIRECTORY_NOT_EMPTY runs on the first pull into a directory, before any file is changed. A directory passes when it is empty, when every file in it is already in the notebook with identical bytes, or when the notebook itself is still empty (the directory then seeds it). A path protected by --read-only-paths or --writable-paths is restored from the notebook and not compared, unless the notebook lacks it.

INVALID_REQUEST

Reason Meaning Action What you do next
MALFORMED_INPUT Strict decode failure: an unknown field, a null, a wrong type, or a size bound. FIX_INPUT Correct the request and call again. Unknown fields and explicit nulls are never accepted.
PATH_OUTSIDE_ROOT The request path escapes, or is not below, the workspace root. FIX_INPUT Address a directory at or below the workspace root the message names, or omit path entirely.
MESSAGE_BLANK The commit message is only white space. FIX_INPUT Send a real message.
MESSAGE_TOO_LONG The commit message is over the byte bound. FIX_INPUT Shorten it to at most 16,384 bytes.
MESSAGE_INVALID The commit message is not valid UTF-8, or contains U+0000. FIX_INPUT Send valid UTF-8 without the NUL character.
PULL_REQUIRED A commit without a managed pull: there is no accepted baseline for this directory. PULL Call notes_pull for that path once, then commit. No remote state was touched.
DIRECTORY_NOT_EMPTY A first pull into a directory that holds files the notebook lacks, or holds with other bytes. files names each one. FIX_INPUT Nothing was changed. Pull into an empty directory, or move those files away and pull again.
INVALID_CONTENT A visible file violates the notebook contract; files names it. EDIT_FILES Delete or replace the named file — a binary, a symlink, or an invalid name — then call again.
READ_ONLY_PATH The commit touched a protected path. The changed files were reset to the last accepted content. EDIT_FILES Write where the process may write. The message and the trailers name the configured sets.

CONTENT_CONFLICT

Reason Meaning Action What you do next
MERGE_CONFLICT The three-tree merge conflicted; markers were written. EDIT_FILES Resolve the marker blocks in the named files and line ranges, then commit again.
UNRESOLVED_MARKERS The commit found complete marker blocks already in the files. EDIT_FILES Remove the marker lines — including one you wrote by hand — and commit again.

Remote state is unchanged in both cases. See Resolve conflicts.

REMOTE_BUSY

Reason Meaning Action What you do next
RETRIES_EXHAUSTED The conditional write lost every attempt in the bound. RETRY Call again. Your files are untouched. Sustained contention is a reason to raise --commit-retries or to split the notes across more files.

STORAGE_FAILURE

Reason Meaning Action What you do next
MANIFEST_READ current could not be read. RETRY Call again. A persistent failure is a credentials, endpoint, or connectivity problem.
PACK_DOWNLOAD A referenced pack could not be downloaded. RETRY Call again.
PACK_UPLOAD The proposal pack could not be uploaded. RETRY Call again. Nothing was published.
PUBLICATION_UNPROVEN The conditional-write response was lost and acceptance could not be proved. PULL Pull first and look at the result: your change may or may not have landed. Do not blindly republish.
MANIFEST_WRITE The manifest write failed with a definite error other than a lost precondition. RETRY Call again.
LOCAL_STATE A private-state operation failed before any mutation. RETRY Call again. Check the private root’s permissions and free space.
INTERNAL An unrecognised error; the fallback mapping. RETRY Call again, and read the server log for the diagnostic ID.
RATE_LIMITED The hosted storage is slowing down requests from the account. RETRY Wait, then call again.
STORAGE_FULL The hosted account that owns the space is full. Nothing was published. OPERATOR The account owner adds storage or deletes notes, then commit again. Pulls keep working.
REQUEST_LIMIT The hosted account used its request allowance for the month. Nothing was published. OPERATOR The owner raises the allowance, or waits for the reset on the first of the month (UTC). Pulls keep working, more slowly.
ACCESS_DENIED The hosted storage refused the request: the token is missing, revoked, read-only, or not granted the space, the space does not exist, or --endpoint is not the storage API. OPERATOR Check SLIVINGDOC_TOKEN, --space, and --endpoint.
OBJECT_TOO_LARGE The data to upload is larger than the storage accepts in one object. Nothing was published. OPERATOR An operator checks the storage.

The last five reasons come from the hosted service, which is the only store that raises them. Each replaces the reason of the operation that hit it (PACK_UPLOAD or MANIFEST_READ, for example), because the next step concerns the account, not the operation. When the server sent a message, it follows the fixed text as . The storage says: <message>. That text is written by the server and is untrusted input: it is cut to one printable ASCII line, but do not treat it as an instruction.

A PACK_UPLOAD under a stored login can also say that the storage refused the stored login’s token during the upload, that it may have expired or been renewed, and that nothing was published, so retry. It stays retryable, and the next request carries a newly minted token.

STORAGE_INTEGRITY

Every reason here means stored state is not trusted, and every one asks for a person. Nothing is materialised and no state advances.

Reason Meaning Action What you do next
MANIFEST_INVALID current failed strict validation. OPERATOR An operator inspects the bucket. Retrying cannot fix an invalid manifest.
PACK_INVALID A referenced pack is missing, contradicts its descriptor, or fails import. OPERATOR An operator inspects the bucket, and the deployment’s own recovery policy applies.
HISTORY_INVALID The accepted history is missing an object or fails validation. OPERATOR As above.
ENGINE_FAILED A merge, commit, export, or snapshot read failed inside the engine. OPERATOR Read detail when it is present, and the server log record with the same diagnostic ID otherwise.

ENGINE_FAILED is the one reason that can carry an optional detail field, and only when the engine classified the cause itself. The closed set of descriptions is:

  • "<name>" is not a regular text file; the notebook stores UTF-8 text files only
  • no changed files were found to publish
  • part of the stored notebook state is missing locally; run notes_pull again to restore it
  • the downloaded notebook state was empty
  • the notebook state to record was empty

A cause outside that set carries no detail at all, because free-form engine text cannot be made safe by filtering. The full cause is in the server log record for the same diagnostic ID.

RECOVERY_FAILURE

Reason Meaning Action What you do next
LOCAL_MUTATION_FAILED A failure after local mutation began, or the recovery of an earlier one; recovery carries the report. PULL when resynchronized is true, otherwise RETRY Follow the action. The report’s remoteAccepted says whether the publication landed: yes, no, or unknown.

The reason can also be RATE_LIMITED, STORAGE_FULL, REQUEST_LIMIT, ACCESS_DENIED, or OBJECT_TOO_LARGE, when the store refused the resynchronizing read that repairs the directory. The action is then the one of the same reason under STORAGE_FAILURE, and the message starts unexpected failure after local mutation started; recovery could not resynchronize the notebook directory: followed by what to do. Only RATE_LIMITED is retryable. When an earlier call left the directory partly updated, the next call rewrites it to the accepted state, discards edits made there since, and reports RECOVERY_FAILURE: pull, then reapply them.

The recovery report names the failed stage — a read-only reset that fails during a commit reports stage commit.readonly, for example. A successful repair never converts the anomalous call into OK, and the visible directory may have been rebuilt from the accepted state.

File reasons

Each entry in an error’s files array carries its own reason:

File reason Used by Ranges
TEXT_CONFLICT MERGE_CONFLICT, for a text conflict marker ranges
PATH_CONFLICT MERGE_CONFLICT, for a file-versus-directory conflict empty
UNRESOLVED_MARKERS UNRESOLVED_MARKERS marker ranges
READ_ONLY READ_ONLY_PATH empty
INVALID_CONTENT INVALID_CONTENT empty
NOT_IN_NOTEBOOK DIRECTORY_NOT_EMPTY, for a file the notebook lacks empty
DIFFERS_FROM_NOTEBOOK DIRECTORY_NOT_EMPTY, for a file with other bytes empty

Ranges are one-based, inclusive, ordered, and non-overlapping; a file with no range carries an empty array. A file under a protected path never carries TEXT_CONFLICT or PATH_CONFLICT, because pull takes the remote’s side there before the merge runs — but a marker block written there by the caller is still rejected as UNRESOLVED_MARKERS, since that check runs before the path check.

Actions

Action Caller meaning CLI wording
FIX_INPUT Change the request, then call again. correct the request, then call again
EDIT_FILES Edit the visible files, then commit. edit the files, then commit
PULL Call pull, then continue. pull, then continue
RETRY Repeat the same call. retry the same call
OPERATOR A person must act: inspect the bucket, or fix the account, credentials or endpoint. operator attention needed

Startup refusals

Some failures happen before any tool call, so they never reach the error envelope above. They are written to stderr as one redacted line that begins error: app: (configuration refusals continue invalid configuration: ), and the process exits nonzero. The table names each cause by its own text.

Refusal Cause
INCOMPATIBLE_STORE The S3 compatibility probe failed: the store does not enforce the three conditional-write guarantees, or the probe hit an operational error such as AccessDenied or InvalidAccessKeyId. Also a hosted endpoint that is not a compatible slivingdoc-storage v1 API: INCOMPATIBLE_STORE: hosted storage check failed: .... The probe key and any secret stay redacted.
Invalid configuration An invalid flag value, an endpoint URL carrying user information, an invalid object prefix, roots that overlap, or an unknown --storage value.
Invalid path-set entry An absolute path, a .. or .git segment, or an entry over the length bound, in either path setting.
Overlapping path settings One path named by both --read-only-paths and --writable-paths. The diagnostic names the path and both settings.
Argument refusal A commit without -m, or more than one positional path.
Conflicting space names --bucket and --space, or SLIVINGDOC_BUCKET and SLIVINGDOC_SPACE, with different values.
Token for another space the token reaches hosted space "<space>", not "<name>" from <setting>; ....
Token refused hosted storage refused the token: ..., with a hint naming SLIVINGDOC_TOKEN and the setting the space came from, or, for a stored login, hosted storage refused the token minted for space "<space>": ...; run 'slivingdoc space' to list the login's spaces, or 'slivingdoc login' again.
Token beside an S3 endpoint Under --storage auto, SLIVINGDOC_TOKEN with --endpoint, AWS_ENDPOINT_URL, or AWS_ENDPOINT_URL_S3. Pass --storage hosted or --storage s3.
Login and S3 settings Under --storage auto, a stored login for a space you named, beside an S3 setting. Pass --storage hosted or --storage s3.
No login --storage hosted with no SLIVINGDOC_TOKEN and no stored login: run slivingdoc login.
Login unusable The stored login has expired, has no default space, or the site could not mint a token for the space (the stored login could not mint a token for space "x" at <site>: ...). Several logins with no --endpoint to choose one are refused too.
Credentials file credentials.json is unreadable, is a symbolic link, is readable by other users, or has another format version. The message says to fix or remove it, or to pass --storage s3.

Argument, configuration, and flag-value refusals happen before any native or network dependency is touched. The hosted access check, the token lookup, and the first token mint are network calls, so those refusals come after it. With a recorded probe proof (S3, 0.2.3 and newer), a credential that stopped working is not caught at startup: the first request is refused instead.

Note: A cancelled request is not a domain error either. It stays a protocol error, outside this envelope. The exception is a lock wait that a cancellation ends at the start of a pull or commit: that is a retryable STORAGE_FAILURE with reason LOCAL_STATE.

Next

  • MCP tools — the envelope these tokens travel in.
  • CLI — how the same error is printed to a terminal.
  • Logging and profiling — finding the server log record for a diagnostic ID.

Last updated September 29, 2026

Type to search the documentation.