{"record":{"id":"4b983fd215eac496","repo":"different-ai/openwork","slug":"auth-client-registration","errorCode":"AUTH_CLIENT_REGISTRATION","errorMessage":"Authorization server did not advertise dynamic registration","messagePattern":"Authorization server did not advertise dynamic registration","errorType":"exception","errorClass":"ProbeFailure","httpStatus":null,"severity":"error","filePath":"packages/enterprise-mcp-mock-server/src/testing/probe.ts","lineNumber":594,"sourceCode":"    const tokenEndpoint = assertPinnedOrigin(issuerMetadata.token_endpoint, baseUrl, \"AUTH_ISSUER_DISCOVERY\")\n    const registrationEndpoint = issuerMetadata.registration_endpoint\n      ? assertPinnedOrigin(issuerMetadata.registration_endpoint, baseUrl, \"AUTH_CLIENT_REGISTRATION\")\n      : undefined\n    revocationEndpoint = issuerMetadata.revocation_endpoint\n      ? assertPinnedOrigin(issuerMetadata.revocation_endpoint, baseUrl, \"AUTH_ISSUER_DISCOVERY\")\n      : null\n    if (!issuerMetadata.code_challenge_methods_supported.includes(\"S256\")) {\n      throw new ProbeFailure(\"AUTH_ISSUER_DISCOVERY\", \"oauth_pkce_unsupported\", \"Authorization server did not advertise PKCE S256\")\n    }\n    recordPassed(phases, \"AUTH_ISSUER_DISCOVERY\", startedAt, \"Authorization-server metadata and PKCE S256 are usable\")\n\n    let clientId = scenario.oauth.clientId\n    let clientSecret = options.credentials?.clientSecret ?? \"\"\n    let tokenAuthMethod: \"none\" | \"client_secret_post\" = profile.oauth.defaultClientAuthenticationMethod\n    startedAt = Date.now()\n    if (scenario.oauth.registration === \"dynamic\") {\n      if (!registrationEndpoint) {\n        throw new ProbeFailure(\"AUTH_CLIENT_REGISTRATION\", \"oauth_client_registration\", \"Authorization server did not advertise dynamic registration\")\n      }\n      tokenAuthMethod = profile.oauth.defaultClientAuthenticationMethod\n      const registrationResponse = await expectOk(\n        await fetchStep(registrationEndpoint, {\n          method: \"POST\",\n          headers: { \"content-type\": \"application/json\" },\n          body: JSON.stringify({\n            redirect_uris: scenario.oauth.redirectUris,\n            token_endpoint_auth_method: tokenAuthMethod,\n            client_name: \"OpenWork enterprise MCP probe\",\n          }),\n        }, \"AUTH_CLIENT_REGISTRATION\", overallDeadline),\n        \"AUTH_CLIENT_REGISTRATION\",\n      )\n      const registration = parseAt(\n        registrationResponseSchema,\n        await parseJson(registrationResponse, \"AUTH_CLIENT_REGISTRATION\", \"oauth_client_registration\"),\n        \"AUTH_CLIENT_REGISTRATION\",","sourceCodeStart":576,"sourceCodeEnd":612,"githubUrl":"https://github.com/different-ai/openwork/blob/2b7df46e8ae1517d64c896c7793d2d52ec845669/packages/enterprise-mcp-mock-server/src/testing/probe.ts#L576-L612","documentation":"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.","triggerScenarios":"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\".","commonSituations":"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\".","solutions":["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).","Fix the authorization server so its oauth-authorization-server metadata advertises a `registration_endpoint` supporting RFC 7591.","Verify the registration_endpoint was not stripped by a proxy/reverse-engineering layer between the probe and the AS metadata."],"exampleFix":"// before\nscenario = { oauth: { registration: \"dynamic\", clientId: undefined } }\n// after\nscenario = { oauth: { registration: \"manual\", clientId: \"my-pre-registered-client-id\" } }","handlingStrategy":"validation","validationCode":"const metadata = await fetch(new URL('/.well-known/oauth-authorization-server', baseUrl)).then(r => r.json())\nif (scenario.oauth.registration === 'dynamic' && !metadata.registration_endpoint) {\n  throw new Error('Scenario requires dynamic registration but AS metadata has no registration_endpoint')\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Match scenario.oauth.registration to the AS's advertised capabilities before running.","Cache and assert AS metadata (registration_endpoint presence) in CI before probe runs.","Default new scenarios to \"manual\" unless the target AS is known to support RFC 7591."],"tags":["oauth","dynamic-client-registration","configuration"],"backgroundTag":"oauth-dynamic-registration-unsupported","analyzedSha":"2b7df46e8ae1517d64c896c7793d2d52ec845669","analyzedAt":"2026-09-01T07:59:23.713Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}