affaan-m/ECC · error
not_found
not_found
Error message
not_found
What it means
REST example from the api-design skill: a resource-level handler for GET /api/v1/orders/:id calls Order.findById, and when the lookup returns null it responds 404 with { error: { code: 'not_found' } } before any ownership check runs. Reaching the 404 means the id simply does not match a row (the ownership 403 is a separate, later branch).
Source
Thrown at skills/api-design/SKILL.md:316
### Token-Based Auth
```
# Bearer token in Authorization header
GET /api/v1/users
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
# API key (for server-to-server)
GET /api/v1/data
X-API-Key: sk_live_abc123
```
### Authorization Patterns
```typescript
// Resource-level: check ownership
app.get("/api/v1/orders/:id", async (req, res) => {
const order = await Order.findById(req.params.id);
if (!order) return res.status(404).json({ error: { code: "not_found" } });
if (order.userId !== req.user.id) return res.status(403).json({ error: { code: "forbidden" } });
return res.json({ data: order });
});
// Role-based: check permissions
app.delete("/api/v1/users/:id", requireRole("admin"), async (req, res) => {
await User.delete(req.params.id);
return res.status(204).send();
});
```
## Rate Limiting
### Headers
```
HTTP/1.1 200 OK
X-RateLimit-Limit: 100View on GitHub (pinned to d8409a4b08)
Solutions
- Verify the id exists by querying the store directly (or the source system that gave you the id)
- Check whether the record was deleted or the id came from a stale cache/another environment
- Confirm the id format matches what the API expects (UUID string vs numeric id) with no whitespace or case drift
- On the client, treat 404 with code 'not_found' as a terminal condition: clear the cached id / redirect, do not retry
Example fix
// before - client assumes the order exists and crashes on undefined
const order = await (await fetch(`/api/v1/orders/${id}`)).json()
render(order.items)
// after - branch on the 404 code
const res = await fetch(`/api/v1/orders/${id}`)
if (res.status === 404) return notFoundScreen()
const { data } = await res.json()
render(data.items) Defensive patterns
Strategy: validation
Validate before calling
// Client: sanity-check the id format before spending a round trip
const isUuid = (id: string) =>
/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(id.trim())
if (!isUuid(orderId)) throw new Error(`malformed order id: ${orderId}`) Try / catch
const res = await fetch(`/api/v1/orders/${encodeURIComponent(orderId)}`)
switch (res.status) {
case 200: return await res.json()
case 404: return null // terminal: caller decides (clear cache / show empty state), do not retry
case 403: throw new ForbiddenError()
default: throw new Error(`unexpected status ${res.status}`)
} Prevention
- Validate id format (UUID/numeric) client-side before requesting
- Treat 404 as a terminal condition, never an automatic retry
- Invalidate cached ids when records can be deleted (or TTL them) so stale references die quickly
- Keep dev/staging ids separate — never reuse ids captured from another environment
When it happens
Trigger: GET /api/v1/orders/:id with an id that was never created, was deleted, or has a typo/extra whitespace; an id in a different format than stored (UUID vs integer); a scoped/filtered findById whose filters exclude the row.
Common situations: Client caching an id from a previous environment (dev id sent to staging); the record was deleted by another user or a cleanup job; test database not seeded; copy-pasting ids with trailing newlines or mismatched case on case-sensitive stores.
Understand the failure class
Background: '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 — this error's family across 20 libraries.
Related errors
AI-assisted analysis of affaan-m/ECC@d8409a4b08 (2026-08-26).
Data as JSON: /api/errors/4500fc73124b22f0.
Report an issue: GitHub.