ErrLookup › Background articles › 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty
'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty
'Could not be found', 'does not exist', 'not found in database', 'not valid', 'not registered' — these errors fire when a library resolves a resource by an identifier you supplied and the lookup returns nothing. You meet them when a delete races your update, a slug or key is typo'd or miscased, the ID actually belongs to another database, user, or environment, or the resource is hidden by permissions or filters rather than truly absent. Across 200 documented records in 20 repositories, this article explains the mechanism, why the same miss surfaces as 400, 404, 500, a typed error code, or a CLI abort, and which fixes hold everywhere.
Distilled from 200 documented records across 20 repositories.
Background
This family lives at the application layer, one step above transport. The call reaches the library's code and the channel works; a lookup then runs — findOne against a table, an equality filter over a fetched list, a map-key compare in a registry, a file-existence check, an OS enumeration of windows and displays — and comes back empty, so the code throws or returns an error naming the resource. No real HTTP request has to fail: LiteLLM's ModelsManagementClient.get() wraps a synthetic requests.exceptions.HTTPError (with an empty Response) around a locally detected miss after a successful list call, and the Electron screen-capture variant surfaces as a failed getUserMedia media request, not an HTTP response at all.
From the caller's side every case shares one shape: you hold a reference you believe is valid — an ID, slug, URI, name, or opaque handle — and the store disagrees. Usually the reference was captured earlier and server state moved on: the row was deleted by a racing request (a second admin removing the same team member, a cascading delete mid-transaction, a double-submit in the UI), the resource was deleted and re-created with a new ID (a re-authorized WebDAV account, a recreated collection), the window or display behind an opaque handle vanished, or the identifier was never re-validated after a restart, a workspace switch, or an environment change.
How the miss surfaces varies more than anything else about the family. Some libraries raise typed errors — LiteLLM's not_found_error with HTTP 404, Appwrite's document_not_found, Rocket.Chat's member-does-not-exist — while others throw plain Errors that the transport layer turns into a generic 500 (Rocket.Chat's integration lookup has no error code to match on). AnythingLLM returns 400 Bad Request for a missing workspace slug on delete, 500 for deleting a missing agent flow, and a bare 404 on its update-pin route, where a completely unknown workspace slug instead dies as a TypeError in the catch handler. CLI tools (occ dav:delete-subscription, siyuan's notebook commands) pre-validate and abort with no side effects. At least one path — an Appwrite function-variables delete — reports its not-found condition under a message about certificate paths, so message text alone cannot always be trusted to name the failure.
The second axis of variation is what 'not found' claims. Often the row is genuinely absent. But Appwrite's GET document runs under the caller's roles and returns the same message whether the document is gone or merely not readable by you — existence is deliberately not leaked — and disabled databases and collections are masked as not-found for session users while API keys and privileged users see the real state. LiteLLM's team bulk-key update deliberately excludes blocked and expired keys, so a team whose keys all expired reports 'No keys found'. Whether missing, forbidden, and filtered-out are distinguished is library-specific; check the record for the exact path you are on.
Common causes
- Stale reference — deleted, removed, or re-created since capture. The resource existed when you captured its identifier but not when you used it. Classic forms: double deletes, two admins removing the same member, a document deleted between list and update or between staging and commit, a WebDAV account re-authorized under a new _id, or a cloud banner that expired between render and dismissal.
- Typo, casing, whitespace, or encoding mismatch. Many lookups are plain equality or exact-string compares — model_name, docPath, slug, manifest name, subscription URI — so 'GPT-4o' vs 'gpt-4o', surrounding whitespace, a truncated ID, or an unencoded special character in a slug still misses. A near-miss reads exactly like a total miss.
- Wrong identifier kind. A name is sent where an ID belongs: a collection name instead of its $id, a thread name instead of a slug, a display name instead of a subscription URI, a device token or UUID instead of the numeric row id, or a directory name instead of the manifest's name field.
- Right ID, wrong scope. The identifier resolves, just not in the namespace queried: a collection from another database, a variable from another function sharing the same project-wide collection, a calendar URI owned by another user principal, a key or model living in another proxy database or environment, or a notebook in another workspace.
- Hidden rather than absent. The resource exists but the lookup cannot see it: read permissions exclude your roles and the server masks it as not-found, the database or collection is disabled for session users, or the query deliberately filters rows — a team whose keys are all blocked or expired reports zero keys.
- Unstable identifiers. Some identifiers are ephemeral by nature: Electron capture source ids embed window and display handles and change across restarts, display changes, and permission revocations, and re-created resources get new IDs. An id cached across such events is dead on arrival.
- Empty success from the lookup channel. The channel reports success but the payload is empty: gh exits 0 with null JSON, a test shim returns nothing, or a model's catch path returns an empty list. The miss is real, but it is a different failure class from a hard lookup error.
- Wrong service or API for the resource type. Calling tablesDB endpoints against a collections-type database, or the deprecated Databases API on a tables database, fails the type-mismatch check but surfaces under the generic 'database could not be found' message.
What usually fixes it
- [object Object]
- [object Object]
- [object Object]
- [object Object]
- [object Object]
- [object Object]
Go deeper
- HTTP status errors: handling 4xx and 5xx responses — how to handle 4xx and 5xx responses properly.
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Documented occurrences
- Source with id ${request.sourceId} not found. (moeru-ai/airi)
- The integration does not exists. (RocketChat/Rocket.Chat)
- Workspace ${slug} or thread ${threadSlug} is not valid. (Mintplex-Labs/anything-llm)
- not_found_error: Key not found in database (BerriAI/litellm)
- Model with id={model_id} not found (BerriAI/litellm)
- Bad Request (Mintplex-Labs/anything-llm)
- installed package not found (siyuan-note/siyuan)
- document_not_found: Document with the requested ID '%s' could not be found. (appwrite/appwrite)
- member-does-not-exist (RocketChat/Rocket.Chat)
- collection_not_found: Collection with the requested ID '%s' could not be found. (appwrite/appwrite)
- Unable to load issue #${issueNumber} from ${repo} (affaan-m/ECC)
- No keys found for team {data.team_id} (BerriAI/litellm)
- database_not_found: Database with the requested ID '%s' could not be found. (appwrite/appwrite)
- server '{server_name}' is not registered (Hmbown/CodeWhale)
- error-invalid-account: Invalid WebDAV Account (RocketChat/Rocket.Chat)
- database_not_found: Database with the requested ID '%s' could not be found. (appwrite/appwrite)
- document_not_found: Document with the requested ID '%s' could not be found. (appwrite/appwrite)
- Organization doesn't exist in db. Organization={org_id}. Create organization via `/organization/new` call. (BerriAI/litellm)
- document_not_found: Document with the requested ID '%s' could not be found. (appwrite/appwrite)
- notebook [%s] not found (siyuan-note/siyuan)
…and 180 more across the corpus — use search.
Honest provenance: generated on 2026-08-20 from AI-assisted analysis of the linked records. See how records are made.