sickn33/agentic-awesome-skills · warning · Error

Not found

Error message

Not found

What it means

Illustrative error from the getUser BEFORE example near line 905: any non-2xx response to GET /api/users/:id throws 'Not found', and the surrounding catch then swallows every failure (including network errors) by logging and returning null. The skill presents this as the anti-pattern: one message for all HTTP failures plus silent fallback.

Source

Thrown at skills/fp-async/SKILL.md:905

| Recover from error | `TE.orElse(fn)` |
| Use default value | `TE.getOrElse(() => T.of(default))` |
| Handle both cases | `TE.fold(onError, onSuccess)` |
| Build up context | `TE.Do` + `TE.bind('name', () => te)` |
| Log without changing | `TE.tap(fn)` |
| Filter with error | `TE.filterOrElse(pred, toError)` |

---

## Before/After Summary

### Fetching Data

```typescript
// BEFORE
async function getUser(id: string) {
  try {
    const res = await fetch(`/api/users/${id}`)
    if (!res.ok) throw new Error('Not found')
    return await res.json()
  } catch (e) {
    console.error(e)
    return null
  }
}

// AFTER
const getUser = (id: string) =>
  TE.tryCatch(
    async () => {
      const res = await fetch(`/api/users/${id}`)
      if (!res.ok) throw new Error('Not found')
      return res.json()
    },
    E.toError
  )
```

View on GitHub (pinned to 58d857988f)

Solutions

  1. Stop returning null from catch — let callers see the failure
  2. Branch on res.status so 404 means 'missing' and other statuses mean 'request failed'
  3. Adopt the AFTER version (line ~918) using TE.tryCatch + E.toError so errors stay in the Left channel
  4. Log with status and body, not just the Error object

Example fix

// before
if (!res.ok) throw new Error('Not found')
catch (e) { console.error(e); return null }
// after
const getUser = (id: string) =>
  TE.tryCatch(async () => {
    const res = await fetch(`/api/users/${id}`)
    if (!res.ok) throw new Error(`HTTP ${res.status}`)
    return res.json()
  }, E.toError)
// callers fold over Left instead of receiving null
Defensive patterns

Strategy: fallback

Validate before calling

const res = await fetch(`/api/users/${id}`)
if (!res.ok) {
  if (res.status === 404) return { kind: 'UserNotFound' }
  throw new Error(`HTTP ${res.status}`)
}

Type guard

const isUser = (u: unknown): u is User =>
  typeof u === 'object' && u !== null && 'id' in u

Try / catch

catch (e) {
  // never blanket-return null; classify and rethrow or return a typed result
  if (e instanceof Error && e.message === 'Not found') return { kind: 'UserNotFound' }
  throw e
}

Prevention

When it happens

Trigger: Unknown user id (404); expired auth returning 401; server 500; network-failure rejected promise — all collapse to null after the catch.

Common situations: UI showing a blank profile because a 500 was silently converted to null; debugging made hard because the error only goes to console.error; developers cannot distinguish 'no such user' from 'request failed' without re-fetching manually.

Related errors


AI-assisted analysis of sickn33/agentic-awesome-skills@58d857988f (2026-08-26). Data as JSON: /api/errors/109549883cd38335. Report an issue: GitHub.