sickn33/agentic-awesome-skills · error · Error
User not found
Error message
User not found
What it means
The second throw in fp-ts-errors' example: db.find(id) returned nothing for a well-formed id. The skill's point is that callers cannot see this failure in the type and must either wrap every call in try/catch or risk runtime crashes.
Source
Thrown at skills/fp-ts-errors/SKILL.md:38
The core idea: **Errors are just data**. Instead of throwing them into the void and hoping someone catches them, return them as values that TypeScript can track.
---
## 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
- Return Either/Error union from getUser so absence is a typed value (the skill's core fix)
- Handle the not-found case explicitly at the caller (render 404, clear session) rather than catching a generic Error
- Add tenant/scope filters so the lookup queries the right data set
Example fix
// before
const user = db.find(id)
if (!user) throw new Error('User not found')
return user
// after
type DomainError = { _tag: 'UserNotFound' } | { _tag: 'InvalidId' }
const getUser = (id: string): E.Either<DomainError, User> => {
if (!id) return E.left({ _tag: 'InvalidId' })
const user = db.find(id)
return user ? E.right(user) : E.left({ _tag: 'UserNotFound' })
} Defensive patterns
Strategy: try-catch
Try / catch
try {
const user = getUser(id)
} catch (e) {
if (e instanceof Error && e.message === 'User not found') {
// 404 / clear stale session
} else throw e
} Prevention
- Prefer Either-returning APIs so absence is a value, not an exception
- Purge session references when accounts are deleted
- Scope DB lookups with tenant context
When it happens
Trigger: Calling getUser with a syntactically valid id that has no row: deleted users, expired sessions referencing purged accounts, or lookups against the wrong database/environment.
Common situations: Session stores holding user ids after account deletion; multi-tenant systems queried without tenant context; 404 handling missing so this throw becomes an unhandled 500.
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
- Age required
- Order not found
- ID required
- HTTP ${response.status}
- HTTP ${response.status}: ${response.statusText}
AI-assisted analysis of sickn33/agentic-awesome-skills@58d857988f (2026-08-26).
Data as JSON: /api/errors/3d5b7fae5617fe44.
Report an issue: GitHub.