anomalyco/sst · error

Unsupported response_type: ${response_type}

Error message

Unsupported response_type: ${response_type}

What it means

SST's AuthHandler OAuth authorize endpoint only supports response_type=code. When the authorization request carries any other response_type (e.g. token, id_token), it responds with HTTP 400 and this plain-text message instead of redirecting with an authorization code.

Source

Thrown at sdk/js/src/auth/handler.ts:200

            if (response_type === "code") {
              // This allows the code to be reused within a 30 second window
              // The code should be single use but we're making this tradeoff to remain stateless
              // In the future can store this in a dynamo table to ensure single use
              const code = await new SignJWT({
                client_id,
                redirect_uri,
                token,
              })
                .setProtectedHeader({ alg: "RS512" })
                .setExpirationTime("30s")
                .sign(await options.signing.privateKey());
              const location = new URL(redirect_uri);
              location.searchParams.set("code", code);
              location.searchParams.set("state", state || "");
              return ctx.redirect(location.toString(), 302);
            }

            ctx.status(400);
            return ctx.text(`Unsupported response_type: ${response_type}`);
          },
        },
        {
          provider: ctx.get("provider"),
          ...properties,
        },
        ctx.req.raw
      );
    },
    forward(ctx: Context, response: Response) {
      return ctx.newResponse(
        response.body,
        response.status as any,
        Object.fromEntries((response.headers as any).entries())
      );
    },
    cookie(c, key, value, maxAge) {

View on GitHub (pinned to a0bd20f762)

Solutions

  1. Change the client to use the authorization code flow: response_type=code in the authorize URL.
  2. Check for typos in the response_type parameter value (must be exactly `code`).
  3. If the client library hardcodes an implicit flow, reconfigure it or use a different provider adapter.
  4. Verify the full authorize URL: client_id, redirect_uri, and response_type are all validated before the redirect is issued.

Example fix

// before
const url = `${authUrl}?client_id=x&redirect_uri=${cb}&response_type=token`;

// after
const url = `${authUrl}?client_id=x&redirect_uri=${cb}&response_type=code`;

export const handler = AuthHandler({
  providers: { /* ... */ },
  callbacks: {
    auth: { success: async (ctx) => ctx.redirect("/"), error: async (ctx) => ctx.redirect("/error") },
  },
});
Defensive patterns

Strategy: validation

Validate before calling

// validate the authorize URL on the client before redirecting
const params = new URL(authorizeUrl).searchParams;
if (params.get("response_type") !== "code") {
  throw new Error(`response_type must be "code", got ${params.get("response_type")}`);
}

Type guard

function usesCodeFlow(params: URLSearchParams): params is URLSearchParams & { get(k: "response_type"): "code" } {
  return params.get("response_type") === "code";
}

Try / catch

// server returns 400 text, not JSON — check status
const res = await fetch(authorizeUrl, { redirect: "manual" });
if (res.status === 400) {
  const body = await res.text();
  if (body.startsWith("Unsupported response_type")) {
    throw new Error("Fix client to use response_type=code");
  }
}

Prevention

When it happens

Trigger: Hitting the auth /authorize route with query parameter response_type set to something other than "code" — e.g. implicit-flow clients sending response_type=token.

Common situations: An OAuth client configured for the implicit flow (response_type=token) pointing at SST's auth handler; hand-crafted authorize URLs with a typo (responseType=code or response_type=codes); a generic OAuth library defaulting to a non-code flow.

Related errors


AI-assisted analysis of anomalyco/sst@a0bd20f762 (2026-08-30). Data as JSON: /api/errors/4caaabb4440e9556. Report an issue: GitHub.