US09-04: Write the User Manual with Generated Screenshots (#110)
This commit was merged in pull request #110.
This commit is contained in:
95
docs/errors.md
Normal file
95
docs/errors.md
Normal file
@@ -0,0 +1,95 @@
|
||||
# Errors and refusals
|
||||
|
||||
[← Documentation index](index.md)
|
||||
|
||||
Every error the API returns carries a code:
|
||||
|
||||
```json
|
||||
{"error": {"code": "lock_held", "message": "a library_write job is already running"}}
|
||||
```
|
||||
|
||||
Most of them are **refusals, not faults**. This application would rather stop and
|
||||
explain than guess about somebody's photographs, so a code below usually means it
|
||||
protected something. Each row says what caused it and what to do.
|
||||
|
||||
## Access and the trust boundary
|
||||
|
||||
| code | cause | what to do |
|
||||
|---|---|---|
|
||||
| `unauthenticated` | no application session | reload the page; the browser bootstraps one |
|
||||
| `access_denied` | wrong or missing access secret | check `PHOTO_PIPELINE_ACCESS_SECRET`. Attempts are logged with the caller's address only |
|
||||
| `too_many_attempts` | more than five failed secret attempts in a minute | wait. This is the rate limit, not a lockout |
|
||||
| `csrf_failed` | a mutation without the session's token | reload; a stale tab has an old token |
|
||||
| `host_not_allowed` | the `Host` header is not a configured name | add the real hostname to `PHOTO_PIPELINE_ALLOWED_HOSTS` |
|
||||
| `origin_not_allowed` | the request came from another origin | not something a browser tab of this app produces |
|
||||
| `cross_site_blocked` | another site triggered the request | expected — this is the protection working |
|
||||
| `payload_too_large` | the body exceeds `PHOTO_PIPELINE_MAX_REQUEST_BYTES` | send less; every endpoint takes small commands |
|
||||
| `path_not_allowed` | a path resolved outside the library roots | usually a symlink. Nothing outside the roots is reachable, by design |
|
||||
|
||||
## The safety gate
|
||||
|
||||
| code | cause | what to do |
|
||||
|---|---|---|
|
||||
| `dry_run_not_approved` | mutation is gated until a dry run is approved | run `dry-run`, read it, then `approve-dry-run` |
|
||||
| `approval_scope_mismatch` | the approval covers different library roots | approve a report for the roots actually configured |
|
||||
| `approval_unreadable` | the approval record cannot be read | re-approve; do not edit it by hand |
|
||||
|
||||
## Concurrency and staleness
|
||||
|
||||
| code | cause | what to do |
|
||||
|---|---|---|
|
||||
| `lock_held` | a mutating job already holds the lane | wait for it. One at a time is what makes a crash recoverable |
|
||||
| `version_conflict` | you acted on a version that changed underneath you | the view re-renders with the server's truth; decide again |
|
||||
| `invalid_transition` | a state change that the machine does not allow | usually a stale tab; reload |
|
||||
| `job_error` | the job service refused the request | the message says why |
|
||||
| `rename_recovery_required` | an interrupted rename is unresolved | resolve it in [Renames](stages/renames.md). Unrelated mutations stay blocked on purpose |
|
||||
|
||||
## Stage refusals
|
||||
|
||||
| code | cause | what to do |
|
||||
|---|---|---|
|
||||
| `nothing_to_score` | no photo is eligible for safety scoring | the queue is already decided |
|
||||
| `nothing_eligible` | no photo is eligible for analysis | resolve safety decisions first |
|
||||
| `nothing_to_plan` | no approved album name to build a plan from | approve a proposal first |
|
||||
| `invalid_decision` | the decision is not one this cluster accepts | reload the cluster |
|
||||
| `invalid_proposal` | the name is empty, reserved, or has forbidden characters | fix the name; the rules are in [Album proposals](stages/albums.md) |
|
||||
| `unknown_album` | the album is not a folder the library knows | rescan |
|
||||
| `cannot_apply` | the plan is invalid, stale, or another plan is unresolved | read the blockers in the preview |
|
||||
| `cannot_rollback` | the operation is complete or its preconditions no longer hold | rollback is recovery, not undo |
|
||||
|
||||
## Upload
|
||||
|
||||
| code | cause | what to do |
|
||||
|---|---|---|
|
||||
| `stale_preflight` | bytes changed between approval and running | re-run preflight; this is the check that stops the wrong bytes being uploaded |
|
||||
| `not_runnable` | the batch is in a state that must not be re-run | an uncertain batch is verified, never retried |
|
||||
| `requires_verification` | the outcome is unknown; the server may hold the files | verify against Immich, then resolve |
|
||||
| `changed_after_upload` | the file changed after a successful upload | uploading again may create or upgrade an asset |
|
||||
|
||||
## Operations
|
||||
|
||||
| code | cause | what to do |
|
||||
|---|---|---|
|
||||
| `backup_failed` | the snapshot could not be taken or verified | check free space and the message |
|
||||
| `invalid_retention` | a `--keep` value that is not a positive count | the newest backup is never pruned |
|
||||
| `not_found` | no such id | usually a stale link |
|
||||
|
||||
## Generic
|
||||
|
||||
| code | cause |
|
||||
|---|---|
|
||||
| `invalid_request` | the request body failed validation. Field names only — never the values, which end up in logs and screenshots |
|
||||
| `http_error` | a plain HTTP-level refusal, with its status |
|
||||
| `internal_error` | an unhandled error. The code is all you get; the traceback is in the server log, because it can carry paths and credentials |
|
||||
|
||||
## Diagnostics warnings
|
||||
|
||||
Not errors — reported by `diagnostics` and worth acting on. They are listed with
|
||||
their meanings in [Diagnostics](stages/diagnostics.md): `disk_low`, `disk_critical`,
|
||||
`cache_over_quota`, `wal_growth`, `tool_version_drift`, `legacy_process_active`, and
|
||||
`no_roots`.
|
||||
|
||||
## Startup refusals
|
||||
|
||||
Exit codes 2 to 5 are covered by the installation manual under
|
||||
[when it refuses to start](installation.md#when-it-refuses-to-start).
|
||||
Reference in New Issue
Block a user