{"record":{"id":"337bfdd06fa6fe1a","repo":"affaan-m/ECC","slug":"unauthorized-337bfd","errorCode":null,"errorMessage":"Unauthorized","messagePattern":"Unauthorized","errorType":"http","errorClass":null,"httpStatus":401,"severity":"error","filePath":"skills/backend-patterns/SKILL.md","lineNumber":111,"sourceCode":"    })\n  }\n\n  private async vectorSearch(embedding: number[], limit: number) {\n    // Vector search implementation\n  }\n}\n```\n\n### Middleware Pattern\n\n```typescript\n// Request/response processing pipeline\nexport function withAuth(handler: NextApiHandler): NextApiHandler {\n  return async (req, res) => {\n    const token = req.headers.authorization?.replace('Bearer ', '')\n\n    if (!token) {\n      return res.status(401).json({ error: 'Unauthorized' })\n    }\n\n    try {\n      const user = await verifyToken(token)\n      req.user = user\n      return handler(req, res)\n    } catch (error) {\n      return res.status(401).json({ error: 'Invalid token' })\n    }\n  }\n}\n\n// Usage\nexport default withAuth(async (req, res) => {\n  // Handler has access to req.user\n})\n```\n","sourceCodeStart":93,"sourceCodeEnd":129,"githubUrl":"https://github.com/affaan-m/ECC/blob/d8409a4b0813771235555e32e3d8046a73988bfa/skills/backend-patterns/SKILL.md#L93-L129","documentation":"The withAuth middleware from the backend-patterns skill wraps Next.js API handlers: it reads req.headers.authorization, strips the 'Bearer ' prefix, and if the result is falsy it short-circuits with 401 { error: 'Unauthorized' }. This specific message means no bearer token reached the handler at all — the 'Invalid token' variant covers tokens that were present but failed verification.","triggerScenarios":"Calling the protected route with no Authorization header; sending the token under the wrong header name (x-api-key instead of Authorization); an empty Authorization header; a corporate proxy or misconfigured CORS setup stripping the Authorization header; fetch call that forgot to attach headers.","commonSituations":"Frontend not yet storing the token (request fired before login completed); auth header dropped by a gateway/reverse proxy; CORS preflight not allowing the Authorization header so the browser omits it; curl test without -H 'Authorization: Bearer ...'.","solutions":["Attach the header: Authorization: Bearer <token> on every request to the wrapped route","Verify the token is actually retrieved from storage before the request fires (await the auth client / check the session is loaded)","If a proxy sits in front, confirm it forwards the Authorization header and CORS allows it (Access-Control-Allow-Headers)","Check header spelling — the middleware only reads req.headers.authorization"],"exampleFix":"// before\nawait fetch('/api/protected', { method: 'GET' })  // 401 Unauthorized\n\n// after\nawait fetch('/api/protected', {\n  headers: { Authorization: `Bearer ${token}` },\n})","handlingStrategy":"validation","validationCode":"// Client: only fire when a token is actually in hand\nfunction authHeaders(token: string | null | undefined): HeadersInit {\n  if (!token) throw new Error('No auth token available — complete login before calling protected routes')\n  return { Authorization: `Bearer ${token}` }\n}","typeGuard":"const hasBearerToken = (h: Headers | Record<string, string>): boolean => {\n  const v = h instanceof Headers ? h.get('authorization') : h['Authorization'] ?? h['authorization']\n  return typeof v === 'string' && v.trim().length > 0\n}","tryCatchPattern":null,"preventionTips":["Centralize authenticated fetch in one client that always attaches the Authorization header","Gate protected UI/actions on session state so requests cannot fire pre-login","When a proxy or CORS layer is involved, verify Authorization survives: allow it in Access-Control-Allow-Headers and proxy config","Remember the distinction: 'Unauthorized' (401) = header missing; 'Invalid token' (401) = header present but failed verification"],"tags":["auth","http-401","middleware","jwt","nextjs"],"backgroundTag":"missing-auth-token","analyzedSha":"d8409a4b0813771235555e32e3d8046a73988bfa","analyzedAt":"2026-08-26T12:15:34.022Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}