sickn33/agentic-awesome-skills · error · Error
User not found
Error message
User not found
What it means
Thrown by the same fp-errors skill example (skills/fp-errors/SKILL.md:45) when db.find(id) returns null/undefined: the requested user does not exist. The point of the doc is that the caller of getUser(id) has no way to know from the type that this call can explode.
Source
Thrown at skills/fp-errors/SKILL.md:45
- You want pragmatic fp-ts error-handling guidance for real application code.
---
## 1. Stop Throwing Everywhere
### The Problem with Exceptions
Exceptions are invisible in your types. They break the contract between functions.
```typescript
// What this function signature promises:
function getUser(id: string): User
// What it actually does:
function getUser(id: string): User {
if (!id) throw new Error('ID required')
const user = db.find(id)
if (!user) throw new Error('User not found')
return user
}
// The caller has no idea this can fail
const user = getUser(id) // Might explode!
```
You end up with code like this:
```typescript
// MESSY: try/catch everywhere
function processOrder(orderId: string) {
let order
try {
order = getOrder(orderId)
} catch (e) {
console.error('Failed to get order')
return nullView on GitHub (pinned to 58d857988f)
Solutions
- Make absence a value: return Either of not-found or User (or Option of User) so callers must handle the missing case
- If staying imperative, throw a typed NotFoundError and centralize a 404 mapper at the API boundary
- Verify id provenance (token freshness, URL params) before lookup
Example fix
// before
const user = getUser(id) // Might explode!
// after
const result = getUser(id)
if (E.isLeft(result)) {
return handleMissingUser(result.left) // e.g. 404
} Defensive patterns
Strategy: type-guard
Validate before calling
const maybeUser = await db.find(id)
if (!maybeUser) return notFound(`no user with id ${id}`) Type guard
const hasUser = (r: unknown): r is { user: User } =>
typeof r === 'object' && r !== null && 'user' in r Try / catch
try {
const user = getUser(id)
} catch (e) {
if (e instanceof Error && e.message === 'User not found') return notFound()
throw e
} Prevention
- Prefer Either/Option returns for lookups that can miss
- Map missing lookups to 404 at the API boundary
- Verify id provenance (token sub, URL params) before lookup
When it happens
Trigger: Calling getUser with a syntactically valid id that has no matching row: deleted accounts, stale ids from JWTs or URLs, race between existence check and lookup.
Common situations: Looking up users from decoded token sub claims after account deletion; following /users/:id links to removed records; test fixtures referencing seeded ids that were never inserted.
Understand the failure class
Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.
Related errors
AI-assisted analysis of sickn33/agentic-awesome-skills@58d857988f (2026-08-26).
Data as JSON: /api/errors/faf8ef31c213459b.
Report an issue: GitHub.