Files
photoanalyzer/docs/errors.md
domverse f1442527a2
Some checks failed
Test / suites (push) Failing after 2m56s
Test / container (push) Failing after 5m27s
US09-04: Write the User Manual with Generated Screenshots (#110)
2026-08-23 23:37:31 +02:00

5.2 KiB

Errors and refusals

← Documentation index

Every error the API returns carries a code:

{"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. 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
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: 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.