{"record":{"id":"8fed901cc5131b1e","repo":"anomalyco/sst","slug":"invalid-grant-type","errorCode":null,"errorMessage":"Invalid grant_type","messagePattern":"Invalid grant_type","errorType":"http","errorClass":null,"httpStatus":400,"severity":"error","filePath":"sdk/js/src/auth/handler.ts","lineNumber":233,"sourceCode":"        Object.fromEntries((response.headers as any).entries())\n      );\n    },\n    cookie(c, key, value, maxAge) {\n      setCookie(c, key, value, {\n        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);","sourceCodeStart":215,"sourceCodeEnd":251,"githubUrl":"https://github.com/anomalyco/sst/blob/a0bd20f762883e72a35caccb4896c42ce5b3f707/sdk/js/src/auth/handler.ts#L215-L251","documentation":"SST's AuthHandler /token endpoint only implements the authorization_code grant. If the posted form's grant_type is anything other than \"authorization_code\", it returns HTTP 400 with this message. It guards the token exchange endpoint against unsupported or malformed token requests.","triggerScenarios":"POSTing to /token with form field grant_type set to refresh_token, password, client_credentials, or missing entirely.","commonSituations":"A token client that auto-refreshes using grant_type=refresh_token, which this handler doesn't support; an OAuth client library sending client_credentials for machine flows; omitting grant_type in a hand-rolled token request; pointing a generic OIDC client at this endpoint.","solutions":["Send grant_type=authorization_code in the /token form body for the initial code exchange.","If you need refresh tokens, implement refresh handling yourself or use a provider that supports it — this handler does not.","Remove/replace client libraries that default to other grant types when talking to this endpoint.","Confirm the request is form-encoded (application/x-www-form-urlencoded) with grant_type present, matching what the authorize step returned."],"exampleFix":"// before\nawait fetch(`${authUrl}/token`, { method: \"POST\", body: new URLSearchParams({ grant_type: \"refresh_token\", refresh_token }) });\n\n// after\nawait fetch(`${authUrl}/token`, {\n  method: \"POST\",\n  body: new URLSearchParams({ grant_type: \"authorization_code\", code, redirect_uri: cb, client_id: id }),\n});","handlingStrategy":"validation","validationCode":"// validate the token request body before sending\nconst body = new URLSearchParams({ grant_type: \"authorization_code\", code, redirect_uri, client_id });\nif (body.get(\"grant_type\") !== \"authorization_code\") throw new Error(\"Only authorization_code grant is supported\");","typeGuard":"function isAuthorizationCodeGrant(form: URLSearchParams): boolean {\n  return form.get(\"grant_type\") === \"authorization_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 === \"Invalid grant_type\") throw new Error(\"Set grant_type=authorization_code\");\n}","preventionTips":["Only send grant_type=authorization_code to SST's /token endpoint.","Disable automatic refresh-token flows in client libraries pointed at this handler.","Send token requests as application/x-www-form-urlencoded form data.","Pin the token-exchange helper to the fields this handler expects: grant_type, code, redirect_uri, client_id."],"tags":["oauth","auth","token-endpoint","http-400"],"backgroundTag":"oauth-invalid-grant-type","analyzedSha":"a0bd20f762883e72a35caccb4896c42ce5b3f707","analyzedAt":"2026-08-30T11:26:00.383Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}