> ## Documentation Index
> Fetch the complete documentation index at: https://docs.elanotes.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Errors

> Stable reason codes, hints, and help anchors used by the HTTP envelope.

`help` on every error is
`{DOCS_PUBLIC_URL}/api/errors#{reason}` with `reason` lowercased.
Follow `hint`. Vocabulary is the initial set from the agentic API plan.

<h2 id="auth_missing">
  AUTH\_MISSING
</h2>

Send `Authorization: Bearer <token>` on this request.

<h2 id="auth_invalid">
  AUTH\_INVALID
</h2>

Request a new access token from the authorization server, then retry with
`Authorization: Bearer <token>`.

<h2 id="vault_forbidden">
  VAULT\_FORBIDDEN
</h2>

Retry with a token whose `vault_id` or mapped `org_id` matches a vault.

<h2 id="permission_missing">
  PERMISSION\_MISSING
</h2>

Retry with a token that includes the missing permission named in the
`WWW-Authenticate` `scope` parameter.

<h2 id="note_not_found">
  NOTE\_NOT\_FOUND
</h2>

`GET /v1/notes` to list slugs in this vault, then retry with a slug that
exists.

<h2 id="version_not_found">
  VERSION\_NOT\_FOUND
</h2>

`GET /v1/notes/{note}:listRevisions` to list revision ids, then retry
restore / rollback with an id from that list.

<h2 id="folder_not_found">
  FOLDER\_NOT\_FOUND
</h2>

`GET /v1/folders` to list paths, then retry with an existing folder path.

<h2 id="attachment_not_found">
  ATTACHMENT\_NOT\_FOUND
</h2>

`GET /v1/attachments` to list file names, then retry with a name that
exists.

<h2 id="attachment_ambiguous">
  ATTACHMENT\_AMBIGUOUS
</h2>

Retry `GET /v1/attachments/{file_name}?sha256=` with one `sha256` from
`details` metadata.

<h2 id="pending_write_not_found">
  PENDING\_WRITE\_NOT\_FOUND
</h2>

`GET /v1/writes` or `GET /v1/writes/{id}` to list pending write ids, then
retry with an id that exists.

<h2 id="route_not_found">
  ROUTE\_NOT\_FOUND
</h2>

`GET /openapi.json` to discover registered paths, then call a documented
route.

<h2 id="validation_failed">
  VALIDATION\_FAILED
</h2>

Fix the `fieldViolations` listed in `details`, then retry the same
request.

<h2 id="invalid_filter">
  INVALID\_FILTER
</h2>

`GET /openapi.json` and retry with a filter that uses only documented
fields and operators. See [filters](/api/overview).

<h2 id="invalid_update_mask">
  INVALID\_UPDATE\_MASK
</h2>

Retry `PATCH` with `update_mask` listing only `title`, `content`,
`folder`, `tags`, `status`, or `frontmatter.<key>`.

<h2 id="unsafe_path">
  UNSAFE\_PATH
</h2>

Retry with a vault-relative path that stays inside the vault and does not
escape.

<h2 id="idempotency_key_missing">
  IDEMPOTENCY\_KEY\_MISSING
</h2>

Retry the write with an `Idempotency-Key` header unique to this
operation.

<h2 id="idempotency_key_reused">
  IDEMPOTENCY\_KEY\_REUSED
</h2>

Retry with a fresh `Idempotency-Key` for this different request body.

<h2 id="version_moved">
  VERSION\_MOVED
</h2>

`GET /v1/notes/{note}` to read the current `version_id`, then retry
`:edit` with that `version_id` and a fresh `Idempotency-Key`.

<h2 id="name_collision">
  NAME\_COLLISION
</h2>

`GET /v1/folders` or `GET /v1/notes` and retry with a path that does not
already exist.

<h2 id="already_decided">
  ALREADY\_DECIDED
</h2>

`GET /v1/writes?status=applied` or `GET /v1/writes?status=rejected` to
list the decision; do not retry the same approve or reject.

<h2 id="already_enabled">
  ALREADY\_ENABLED
</h2>

`GET /v1/sync/e2ee`; private notes are already enabled for this vault.

<h2 id="edit_ambiguous">
  EDIT\_AMBIGUOUS
</h2>

Retry `:edit` with a longer unique `old_string` that matches exactly one
place.

<h2 id="edit_match_not_found">
  EDIT\_MATCH\_NOT\_FOUND
</h2>

`GET /v1/notes/{note}` and retry `:edit` with an `old_string` that
appears in the current body.

<h2 id="write_refused">
  WRITE\_REFUSED
</h2>

`GET /v1/vault/write-settings` and `GET /v1/writes`, then retry with a
payload the policy allows.

<h2 id="write_budget_exceeded">
  WRITE\_BUDGET\_EXCEEDED
</h2>

`GET /v1/writes` for a reviewer to apply remaining work, or wait until
the budget window resets and retry with a fresh `Idempotency-Key`.

<h2 id="rate_limited">
  RATE\_LIMITED
</h2>

Wait the `Retry-After` seconds, then retry the same request with the
same `Idempotency-Key`.

<h2 id="sync_compacted">
  SYNC\_COMPACTED
</h2>

`GET /v1/sync/snapshot`, then `GET /v1/sync/ops` with `after_seq` set to
`compacted_through_seq` from `details`.

<h2 id="storage_unavailable">
  STORAGE\_UNAVAILABLE
</h2>

Set `DATABASE_URL` and start Postgres, then retry this request.

<h2 id="blob_store_unavailable">
  BLOB\_STORE\_UNAVAILABLE
</h2>

Set `BLOB_*`, then retry `GET /v1/attachments/{file_name}`.

<h2 id="unsupported_media_type">
  UNSUPPORTED\_MEDIA\_TYPE
</h2>

Retry `POST /v1/attachments` with an allowed attachment type.

<h2 id="payload_too_large">
  PAYLOAD\_TOO\_LARGE
</h2>

Retry `POST /v1/attachments` with a file under the documented byte cap.

<h2 id="internal">
  INTERNAL
</h2>

Retry the same request; if it persists, include the `requestId` when
reporting the failure.
