different-ai/openwork · error · ProbeFailure

AUTH_CLIENT_REGISTRATION

AUTH_CLIENT_REGISTRATION

Error message

Authorization server did not advertise dynamic registration

What it means

The probe selected a scenario whose `scenario.oauth.registration` is "dynamic", meaning it expects the authorization server to support RFC 7591 dynamic client registration. Before registering a client, the probe checks whether the authorization-server metadata (fetched during AUTH_ISSUER_DISCOVERY) advertised a `registration_endpoint`. If none was advertised, the probe cannot self-register and fails with AUTH_CLIENT_REGISTRATION / oauth_client_registration.

Source

Thrown at packages/enterprise-mcp-mock-server/src/testing/probe.ts:594

    const tokenEndpoint = assertPinnedOrigin(issuerMetadata.token_endpoint, baseUrl, "AUTH_ISSUER_DISCOVERY")
    const registrationEndpoint = issuerMetadata.registration_endpoint
      ? assertPinnedOrigin(issuerMetadata.registration_endpoint, baseUrl, "AUTH_CLIENT_REGISTRATION")
      : undefined
    revocationEndpoint = issuerMetadata.revocation_endpoint
      ? assertPinnedOrigin(issuerMetadata.revocation_endpoint, baseUrl, "AUTH_ISSUER_DISCOVERY")
      : null
    if (!issuerMetadata.code_challenge_methods_supported.includes("S256")) {
      throw new ProbeFailure("AUTH_ISSUER_DISCOVERY", "oauth_pkce_unsupported", "Authorization server did not advertise PKCE S256")
    }
    recordPassed(phases, "AUTH_ISSUER_DISCOVERY", startedAt, "Authorization-server metadata and PKCE S256 are usable")

    let clientId = scenario.oauth.clientId
    let clientSecret = options.credentials?.clientSecret ?? ""
    let tokenAuthMethod: "none" | "client_secret_post" = profile.oauth.defaultClientAuthenticationMethod
    startedAt = Date.now()
    if (scenario.oauth.registration === "dynamic") {
      if (!registrationEndpoint) {
        throw new ProbeFailure("AUTH_CLIENT_REGISTRATION", "oauth_client_registration", "Authorization server did not advertise dynamic registration")
      }
      tokenAuthMethod = profile.oauth.defaultClientAuthenticationMethod
      const registrationResponse = await expectOk(
        await fetchStep(registrationEndpoint, {
          method: "POST",
          headers: { "content-type": "application/json" },
          body: JSON.stringify({
            redirect_uris: scenario.oauth.redirectUris,
            token_endpoint_auth_method: tokenAuthMethod,
            client_name: "OpenWork enterprise MCP probe",
          }),
        }, "AUTH_CLIENT_REGISTRATION", overallDeadline),
        "AUTH_CLIENT_REGISTRATION",
      )
      const registration = parseAt(
        registrationResponseSchema,
        await parseJson(registrationResponse, "AUTH_CLIENT_REGISTRATION", "oauth_client_registration"),
        "AUTH_CLIENT_REGISTRATION",

View on GitHub (pinned to 2b7df46e8a)

Solutions

  1. Change the scenario's oauth.registration from "dynamic" to "manual" and supply scenario.oauth.clientId (plus a client secret if the profile uses client_secret_post).
  2. Fix the authorization server so its oauth-authorization-server metadata advertises a `registration_endpoint` supporting RFC 7591.
  3. Verify the registration_endpoint was not stripped by a proxy/reverse-engineering layer between the probe and the AS metadata.

Example fix

// before
scenario = { oauth: { registration: "dynamic", clientId: undefined } }
// after
scenario = { oauth: { registration: "manual", clientId: "my-pre-registered-client-id" } }
Defensive patterns

Strategy: validation

Validate before calling

const metadata = await fetch(new URL('/.well-known/oauth-authorization-server', baseUrl)).then(r => r.json())
if (scenario.oauth.registration === 'dynamic' && !metadata.registration_endpoint) {
  throw new Error('Scenario requires dynamic registration but AS metadata has no registration_endpoint')
}

Prevention

When it happens

Trigger: Calling probeEnterpriseMcpMockServer against an authorization server whose /.well-known/oauth-authorization-server metadata omits `registration_endpoint` (see probe.ts:577-579) while the scenario under test sets oauth.registration to "dynamic".

Common situations: Pointing the probe at an AS that only supports pre-registered/static clients (e.g. a legacy IdP or a metadata document missing registration_endpoint); a metadata schema change or downgrade on the server removing the registration endpoint; misclassifying a scenario as dynamic when it should be "manual".

Related errors


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