sickn33/agentic-awesome-skills · warning · Error

No user

Error message

No user

What it means

This error is thrown by an illustrative BEFORE code sample in the fp-async skill documentation (skills/fp-async/SKILL.md:933). It demonstrates the imperative pattern of manually checking each awaited result in an async chain and throwing stringly-typed Errors when a lookup fails; the doc contrasts it with a TaskEither pipeline where failures are expressed in the return type. It is not thrown by any real library code.

Source

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

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

### Chained Operations

```typescript
// BEFORE
async function processOrder(orderId: string) {
  const order = await fetchOrder(orderId)
  if (!order) throw new Error('No order')
  const user = await fetchUser(order.userId)
  if (!user) throw new Error('No user')
  const result = await chargePayment(user, order.total)
  return result
}

// AFTER
const processOrder = (orderId: string) =>
  pipe(
    TE.Do,
    TE.bind('order', () => fetchOrder(orderId)),
    TE.bind('user', ({ order }) => fetchUser(order.userId)),
    TE.chain(({ user, order }) => chargePayment(user, order.total))
  )
```

### Error Recovery

```typescript
// BEFORE

View on GitHub (pinned to 58d857988f)

Solutions

  1. Replace the throwing chain with the AFTER pattern shown in the same doc: model fetchOrder/fetchUser as TaskEither and use TE.bind/TE.chain so absence is a Left value, not an exception
  2. If keeping imperative code, narrow the error with a typed error class instead of a bare Error
  3. Check data integrity if the user genuinely should exist: verify the user record was not deleted and the userId field is correct

Example fix

// before
const user = await fetchUser(order.userId)
if (!user) throw new Error('No user')
const result = await chargePayment(user, order.total)

// after
const processOrder = (orderId: string) =>
  pipe(
    TE.Do,
    TE.bind('order', () => fetchOrder(orderId)),
    TE.bind('user', ({ order }) => fetchUser(order.userId)),
    TE.chain(({ user, order }) => chargePayment(user, order.total))
  )
Defensive patterns

Strategy: type-guard

Validate before calling

const user = await fetchUser(order.userId)
if (!user) {
  return res.status(404).json({ error: 'user not found' })
}

Type guard

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

Prevention

When it happens

Trigger: Calling the documented processOrder(orderId) example when fetchUser(order.userId) resolves to a falsy value (null/undefined), e.g. the order references a userId that no longer exists in the user store.

Common situations: Copy-pasting the BEFORE example into real code; data-integrity issues where an order userId points at a deleted user; treating a missing related record as an exception rather than a domain result.

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/114afd4fae39f397. Report an issue: GitHub.