different-ai/openwork · error

Failed to rotate SCIM token (${response.status}).

Error message

Failed to rotate SCIM token (${response.status}).

What it means

handleRotateToken in scim-screen.tsx throws this when POST /v1/scim/token with an empty body returns non-ok. Token rotation is a privileged, single-shot operation; the error means the Den API refused it. Note a follow-up error ('rotation succeeded, but the response was incomplete') exists for a 2xx with a bad payload — this one is strictly the non-ok branch.

Source

Thrown at ee/apps/den-web/app/(den)/dashboard/_components/scim-screen.tsx:175

    if (!orgId) {
      setError("Organization not found.");
      return;
    }

    setError(null);
    setVisibleToken(null);
    try {
      await runReauthableAction("rotate-scim-token", async () => {
        setRotating(true);
        try {
          const { response, payload } = await requestJson(
            "/v1/scim/token",
            { method: "POST", body: JSON.stringify({}) },
            12000,
          );

          if (!response.ok) {
            throw getRequestError(payload, response, `Failed to rotate SCIM token (${response.status}).`);
          }

          const parsed = parseOrgScimPayload(payload);
          if (!parsed.baseUrl || !parsed.connection || !parsed.scimToken) {
            throw new Error("SCIM token rotation succeeded, but the response was incomplete.");
          }

          setBaseUrl(parsed.baseUrl);
          setSsoReady(parsed.ssoReady);
          setConnection(parsed.connection);
          setHealth(parsed.health);
          setVisibleToken(parsed.scimToken);
          setCopiedValue(null);
        } finally {
          setRotating(false);
        }
      });
    } catch (nextError) {

View on GitHub (pinned to 2b7df46e8a)

Solutions

  1. Ensure a SCIM connection exists first — rotation without a connection returns 404.
  2. For 401, re-authenticate; for 403, switch to an org-admin account.
  3. Retry once after transient 5xx; if 409, coordinate with other admins and rotate once.
  4. After success, immediately copy the new token — it is only shown once.

Example fix

// before
await rotateToken();
// after: require an existing connection first
if (!connection) {
  throw new Error('Provision the SCIM connection before rotating its token.');
}
await rotateToken();
Defensive patterns

Strategy: try-catch

Validate before calling

if (!connection) {
  throw new Error('Create the SCIM connection before rotating its token.');
}
const session = await auth.getSession();
if (!session) redirectToSignIn();

Type guard

function hasConnection(v: unknown): v is { connection: Record<string, unknown> } {
  return typeof v === 'object' && v !== null &&
    typeof (v as Record<string, unknown>).connection === 'object' &&
    (v as Record<string, unknown>).connection !== null;
}

Try / catch

try {
  await rotateToken();
  toast('New SCIM token generated — copy it now; it will not be shown again.');
} catch (e) {
  const msg = e instanceof Error ? e.message : String(e);
  if (msg.includes('404')) toast('No SCIM connection exists yet.');
  else if (msg.includes('403')) toast('Only org admins can rotate the SCIM token.');
  else toast(msg);
}

Prevention

When it happens

Trigger: POST /v1/scim/token returns 401 (session expired), 403 (caller is not an org admin), 404 (no SCIM connection exists to rotate a token for), 409/412 (concurrent rotation), or 5xx.

Common situations: Admin clicks 'Rotate token' while their session just expired; rotating before any SCIM connection has been established; two admins rotating simultaneously; server hiccup during the write.

Related errors


AI-assisted analysis of different-ai/openwork@2b7df46e8a (2026-09-01). Data as JSON: /api/errors/33582933bdbf520b. Report an issue: GitHub.