ErrLookup › Background articles › "Not Found" / HTTP 404 Errors: What They Mean and How to Fix Them Across Libraries
"Not Found" / HTTP 404 Errors: What They Mean and How to Fix Them Across Libraries
"Not found" errors are HTTP 404 responses and typed NotFound exceptions raised when a resource — a conversation, package, tag, pipeline, document version, or credential — does not exist or is not visible to the caller. Developers meet this family when an ID in a request is stale, deleted, mistyped, belongs to another tenant, or is hidden by an access policy, and the library deliberately answers 404 instead of a server error.
Distilled from 159 documented records across 6 repositories.
Background
The NotFound family is not one code path but a convention: every library in this set translates an empty lookup result into an HTTP 404 or a typed NotFound exception. At the lowest layer sits the same pattern — a controller or service looks up a resource by some identifier, gets nothing back (an undefined value, an empty array, a zero count, or a falsy row), and raises NotFound so the caller receives a deliberate, machine-readable 'not found' state rather than a crash or an empty 200. Dify wraps service-layer errors like ConversationNotExistsError into Flask/werkzeug NotFound responses; badges/shields throws its own NotFound class inside badge services; payloadcms/payload and nocodb throw typed NotFound errors with 404 semantics.
A recurring and important quirk across the family is that upstream APIs often signal absence with HTTP 200 rather than 404, forcing the library layer to invent the 404. The AUR RPC API returns 200 with resultcount: 0; the JetBrains plugin repository returns 200 with an empty plugin-repository XML body; Docker Hub returns a listing with count: 0 for nonexistent repos; NuGet's search returns an empty data array; GitHub returns an empty commit array. Shields' services explicitly validate these payloads and throw NotFound so the badge renders a clean 'not found' state. This means a 404 from the library does not necessarily correspond to a 404 on the wire — it can mean 'the transport succeeded but the result set was empty.'
Several libraries also use 404 as a security measure. NocoDB deliberately returns NcError.notFound instead of 403 for resources a user lacks permission to see, to avoid confirming existence to unauthorized callers. Payload distinguishes the two cases: a plain boolean access policy yields a 404 for missing documents, while a where-based access policy that excludes the document yields Forbidden (403) instead. Dify scopes lookups by tenant_id, so a binding or credential belonging to another tenant simply 'does not exist.' In these systems, a 404 means 'you cannot have this or it is not there,' and the caller should not retry.
The distinguishing trait of the family is that 404s here are terminal, not transient. Whether it is a conversation_id pointing at a deleted conversation in Dify, a dist-tag missing from an npm package, a pipeline definition with no completed builds in Azure DevOps, or a document id that was hard-deleted in Payload, the resource the request names is gone or never was. The correct client behavior, echoed across nearly every record, is to refresh the listing, re-authorize, or start fresh — not to retry.
Common causes
- Stale or cached identifier. The most common trigger: a client caches an id (conversation_id, upload_file_id, binding_id, last_id cursor, workflow_id) that was later deleted or invalidated. Dify's conversation 404s, upload_file_id failures, and data-source binding errors all fall here. Fix on the client by refreshing the list and discarding cached ids.
- Referenced resource was deleted or expired. The resource existed when the workflow was built but was removed since: a Notion credential revoked, a conversation purged by a retention job, an upload cleaned up in the background, an AUR or NuGet package deleted, a Docker tag removed after an upgrade. Embedded references (badge URLs, persisted queries) break silently.
- Typo or wrong name in the request. Identifiers are often matched exactly and case-sensitively: an npm dist-tag misspelled, a Docker tag that must match exactly, a repo key not present in a ROS distro's distribution.yml, a wrong plugin XML id, a bad groupId:artifactId in Nexus. Copy ids and names directly from the authoritative source.
- ID belongs to another tenant, app, or collection. Many lookups are scoped — by tenant_id in Dify and NocoDB, by app_id for conversations and workflows, by collection in Payload. A valid id used against the wrong scope returns not-found even though the resource exists elsewhere. Confirm the id and its owning context match.
- Wrong resource type or repository variant. Semantic mismatches produce 404s: sending a conversation_id to a completion (single-turn) app, requesting a release version from a Nexus snapshot repo, pointing a badge at a repo that only has git tags but no GitHub Releases, or passing an id from the wrong Payload collection.
- Empty result set from an upstream API. Upstream services that answer HTTP 200 with empty data — AUR resultcount 0, JetBrains empty XML, Docker Hub count 0, NuGet empty data array, GitHub empty commit list — get translated into NotFound by the consuming library. The badge or service layer deliberately manufactures the 404.
- Access hidden as 404. Some systems intentionally return 404 instead of 403 for resources the caller cannot see (NocoDB, and Payload when where-access policies exclude a document). A private Docker repo or inaccessible Azure DevOps pipeline also surfaces as an empty result and then not-found. Check permissions before assuming deletion.
- Feature never configured. Some 404s mean 'nothing was ever set up': GitLab returns 'not set up' when no coverage regex is configured so no coverage was ever recorded, and TestSpace spaces with zero published test results cannot produce counts.
What usually fixes it
- [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.
Documented occurrences
- Conversation Not Exists. (langgenius/dify)
- Conversation Not Exists. (langgenius/dify)
- tag not found (badges/shields)
- space not found or results purged (badges/shields)
- build pipeline not found (badges/shields)
- Not Found (payloadcms/payload)
- Not found (nocodb/nocodb)
- Credential not found. (langgenius/dify)
- artifact or ${versionType}version not found (badges/shields)
- UploadFile not found. (langgenius/dify)
- repo not found: ${repoName} (badges/shields)
- package not found (badges/shields)
- package not found (badges/shields)
- Last Conversation Not Exists. (langgenius/dify)
- repository not found (badges/shields)
- changesetRevision not found (badges/shields)
- not found (badges/shields)
- tag not found (badges/shields)
- Workflow not found (langgenius/dify)
- Data source binding not found. (langgenius/dify)
…and 139 more across the corpus — use search.
Honest provenance: generated on 2026-08-30 from AI-assisted analysis of the linked records. See how records are made.