diegosouzapw/OmniRoute · error

Client registration failed

Error message

Client registration failed: ${error}

What it means

Step 1 of Kiro's OAuth flow: the AWS SSO OIDC client-registration call (registerClientUrl POST) returned non-ok; the raw body is appended. The registerPayload may include issuerUrl only for non-IDC flows (it is deliberately skipped for enterprise IDC tenants to avoid invalid_request). Failure means AWS SSO rejected the client registration — often a bad issuerUrl/startUrl combination or an AWS-side error.

Solutions

  1. Read the appended AWS error body (e.g. InvalidRequestException, unauthorizedClient)
  2. For enterprise IDC startUrls, ensure skipIssuerUrlForRegistration is set so a fixed issuerUrl is not sent
  3. Verify issuerUrl matches the tenant's actual identity store issuer
  4. Retry on transient AWS 5xx with backoff
Defensive patterns

Strategy: try-catch

When it happens

Trigger: Thrown at src/lib/oauth/providers/kiro.ts:44 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of diegosouzapw/OmniRoute@a179ffed5b (2026-08-25). Data as JSON: /api/errors/9b7a98da303b4204. Report an issue: GitHub.

Appendix: source

Thrown at src/lib/oauth/providers/kiro.ts:44

    // For enterprise IDC custom startUrl flows, issuerUrl can differ per tenant.
    // Sending a fixed issuerUrl often causes invalid_request during device auth.
    if (config.issuerUrl && !config.skipIssuerUrlForRegistration) {
      registerPayload.issuerUrl = config.issuerUrl;
    }

    // Step 1: Register client with AWS SSO OIDC
    const registerRes = await fetch(config.registerClientUrl, {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        Accept: "application/json",
      },
      body: JSON.stringify(registerPayload),
    });

    if (!registerRes.ok) {
      const error = await registerRes.text();
      throw new Error(`Client registration failed: ${error}`);
    }

    const clientInfo = await registerRes.json();

    // Step 2: Request device authorization
    const deviceRes = await fetch(config.deviceAuthUrl, {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        Accept: "application/json",
      },
      body: JSON.stringify({
        clientId: clientInfo.clientId,
        clientSecret: clientInfo.clientSecret,
        startUrl: config.startUrl,
      }),
    });

View on GitHub (pinned to a179ffed5b)