affaan-m/ECC · error

INTERNAL_ERROR

INTERNAL_ERROR

Error message

An unexpected error occurred

What it means

The catch-all branch of handleApiError in the error-handling skill: any thrown error that is neither the custom ApiError nor a z.ZodError is logged server-side with console.error('Unexpected error:', error) and returned to the client as HTTP 500 with a generic { code: 'INTERNAL_ERROR', message: 'An unexpected error occurred' } body. The design deliberately hides internals (stack traces, driver messages) from the client while preserving them in server logs.

Source

Thrown at skills/error-handling/SKILL.md:153

    return NextResponse.json(
      {
        error: {
          code: 'VALIDATION_ERROR',
          message: 'Request validation failed',
          details: error.issues.map(i => ({
            field: i.path.join('.'),
            message: i.message,
          })),
        },
      },
      { status: 422 },
    )
  }

  // Unexpected error — log details, return generic message
  console.error('Unexpected error:', error)
  return NextResponse.json(
    { error: { code: 'INTERNAL_ERROR', message: 'An unexpected error occurred' } },
    { status: 500 },
  )
}

export async function POST(req: NextRequest) {
  try {
    // ... handler logic
  } catch (error) {
    return handleApiError(error)
  }
}
```

### React Error Boundary

```typescript
import { Component, ErrorInfo, ReactNode } from 'react'

View on GitHub (pinned to d8409a4b08)

Solutions

  1. Check the server-side logs for the 'Unexpected error:' line — the real error and stack are there, not in the 4xx/500 response body
  2. Reproduce the request locally and add a temporary breakpoint or log around the failing call
  3. Once identified, handle that failure explicitly (custom ApiError with the right status, or a null check) instead of letting it fall through
  4. If it is a missing env var, validate required secrets at startup so the app fails fast with a clear message

Example fix

// before - null row falls through to the 500 catch-all
const user = await db.user.findUnique({ where: { id } })
return NextResponse.json({ data: user.profile })  // user is null -> TypeError -> 500

// after - explicit check with a specific error
const user = await db.user.findUnique({ where: { id } })
if (!user) throw new ApiError(404, 'User not found')
return NextResponse.json({ data: user.profile })
Defensive patterns

Strategy: try-catch

Validate before calling

// Fail fast on required config at startup so this 500 never originates from missing env
const REQUIRED = ['DATABASE_URL', 'JWT_SECRET'] as const
for (const key of REQUIRED) {
  if (!process.env[key]) throw new Error(`Missing required env var: ${key}`)
}

Try / catch

// Keep the ordered cascade: known errors first, generic last, and always log the cause server-side
try {
  return await handler(req)
} catch (error) {
  if (error instanceof ApiError) return respond(error.statusCode, error.code, error.message)
  if (error instanceof z.ZodError) return respond422(error.issues)
  console.error('Unexpected error:', error) // full stack stays in server logs
  return respond(500, 'INTERNAL_ERROR', 'An unexpected error occurred') // client-safe
}

Prevention

When it happens

Trigger: A database/Redis/Supabase connection failure inside the handler; an unguarded TypeError (reading a property of undefined from a null DB row); a missing environment variable used at call time; JSON.stringify choking on a BigInt or circular structure; a third-party SDK throwing its own error type.

Common situations: Env var present locally but missing in the deployed environment; a null database record dereferenced without a check; external service outage surfacing as a raw driver exception; Date/BigInt serialization bugs that only appear with real data.

Related errors


AI-assisted analysis of affaan-m/ECC@d8409a4b08 (2026-08-26). Data as JSON: /api/errors/f6fae3a3c1b4e484. Report an issue: GitHub.