sickn33/agentic-awesome-skills · error · Error
ID required
Error message
ID required
What it means
Part of the hidden-failure-mode example in the fp-errors skill (skills/fp-errors/SKILL.md:43). It is thrown synchronously by getUser when called with an empty or falsy id, despite the signature function getUser(id: string): User promising an unconditional User. The doc uses it to show why unchecked exceptions make signatures lie.
Source
Thrown at skills/fp-errors/SKILL.md:43
- You need to replace exception-heavy code with `Either` or `TaskEither`.
- The task involves validation, domain errors, or clearer error contracts in TypeScript.
- 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) {View on GitHub (pinned to 58d857988f)
Solutions
- Validate and reject empty ids at the system boundary (request parsing) before calling getUser
- Change the signature to make failure explicit: return Either of an error or User, or throw a typed ValidationError the caller must acknowledge
- Use a branded non-empty-string type for id parameters
Example fix
// before
function getUser(id: string): User {
if (!id) throw new Error('ID required')
// ...
}
// after
const getUser = (id: NonEmptyString): E.Either<UserError, User> =>
pipe(
db.find(id),
E.fromNullable({ tag: 'not-found' } as const)
) Defensive patterns
Strategy: validation
Validate before calling
const isNonEmpty = (s: string): boolean => s.trim().length > 0
if (!isNonEmpty(id)) {
return badRequest('id must be a non-empty string')
} Type guard
type NonEmptyString = string & { readonly brand: unique symbol }
const nonEmpty = (s: string): s is NonEmptyString => s.trim().length > 0 Prevention
- Validate route params at the request boundary
- Use branded non-empty string types for ids
- Make functions return Either instead of throwing for bad input
When it happens
Trigger: Calling getUser with an empty string or a nullish value cast to any: any falsy id fails the if (!id) guard before the db.find lookup happens.
Common situations: Passing an unvalidated request parameter or form field straight into a lookup function; optional path/route params defaulting to empty string; refactoring a signature to accept id without validating at the boundary.
Related errors
AI-assisted analysis of sickn33/agentic-awesome-skills@58d857988f (2026-08-26).
Data as JSON: /api/errors/82a74b23747a185f.
Report an issue: GitHub.