{"record":{"id":"7739a679b72848d0","repo":"anomalyco/sst","slug":"missing-code","errorCode":null,"errorMessage":"Missing code","messagePattern":"Missing code","errorType":"http","errorClass":null,"httpStatus":400,"severity":"error","filePath":"sdk/js/src/auth/handler.ts","lineNumber":238,"sourceCode":"        maxAge,\n        httpOnly: true,\n        ...(c.req.url.startsWith(\"https://\")\n          ? { secure: true, sameSite: \"None\" }\n          : {}),\n      });\n    },\n  };\n\n  app.post(\"/token\", async (c) => {\n    console.log(\"token request\");\n    const form = await c.req.formData();\n    if (form.get(\"grant_type\") !== \"authorization_code\") {\n      c.status(400);\n      return c.text(\"Invalid grant_type\");\n    }\n    const code = form.get(\"code\");\n    if (!code) {\n      c.status(400);\n      return c.text(\"Missing code\");\n    }\n\n    const { payload } = await jwtVerify(\n      code as string,\n      await options.signing.publicKey()\n    );\n    if (payload.redirect_uri !== form.get(\"redirect_uri\")) {\n      c.status(400);\n      return c.text(\"redirect_uri mismatch\");\n    }\n    if (payload.client_id !== form.get(\"client_id\")) {\n      c.status(400);\n      return c.text(\"client_id mismatch\");\n    }\n\n    return c.json({\n      access_token: payload.token,","sourceCodeStart":220,"sourceCodeEnd":256,"githubUrl":"https://github.com/anomalyco/sst/blob/a0bd20f762883e72a35caccb4896c42ce5b3f707/sdk/js/src/auth/handler.ts#L220-L256","documentation":"After validating grant_type, the /token endpoint requires a code form field containing the signed authorization-code JWT. If code is absent or empty, it returns HTTP 400 with \"Missing code\". The code is what carries the pending auth state between the authorize redirect and the token exchange.","triggerScenarios":"POSTing to /token with grant_type=authorization_code but no code field in the form body, or an empty-string code (form.get(\"code\") returns null/empty).","commonSituations":"A hand-written token exchange that forgot to forward the code query parameter from the authorize redirect callback; a client that drops query params when reconstructing the callback URL; sending JSON instead of form-encoded data so formData() yields no code.","solutions":["Include the code from the authorize redirect's query string in the /token form body.","Ensure the request body is form-encoded (URLSearchParams / application/x-www-form-urlencoded), not JSON.","Confirm the client's redirect handler actually reads and forwards req.query.code from the callback URL.","Log the outgoing form body before the fetch to verify all required fields (code, redirect_uri, client_id) are present."],"exampleFix":"// before\nconst res = await fetch(`${authUrl}/token`, { method: \"POST\", body: new URLSearchParams({ grant_type: \"authorization_code\" }) });\n\n// after\nconst code = new URL(callbackUrl).searchParams.get(\"code\");\nconst res = await fetch(`${authUrl}/token`, {\n  method: \"POST\",\n  body: new URLSearchParams({ grant_type: \"authorization_code\", code: code!, redirect_uri: cb, client_id: id }),\n});","handlingStrategy":"validation","validationCode":"const code = new URL(callbackUrl).searchParams.get(\"code\");\nif (!code) throw new Error(\"No ?code in authorize redirect callback — cannot exchange at /token\");","typeGuard":"function hasCode(url: string): url is string & { } {\n  return Boolean(new URL(url, \"http://x\").searchParams.get(\"code\"));\n}","tryCatchPattern":"const res = await fetch(`${authUrl}/token`, { method: \"POST\", body });\nif (res.status === 400) {\n  const msg = await res.text();\n  if (msg === \"Missing code\") throw new Error(\"Forward the code query param from the authorize redirect\");\n}","preventionTips":["Always read code from the redirect callback's query string before exchanging.","Send form-encoded bodies (URLSearchParams), not JSON, to /token.","Log the form body in dev to confirm code, redirect_uri, and client_id are all present.","Handle the callback URL on the server side where query params are preserved."],"tags":["oauth","auth","token-endpoint","missing-parameter"],"backgroundTag":"oauth-missing-code","analyzedSha":"a0bd20f762883e72a35caccb4896c42ce5b3f707","analyzedAt":"2026-08-30T11:26:00.383Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}