{"record":{"id":"f1309baec2539c2f","repo":"langgenius/dify","slug":"client-id-is-required","errorCode":null,"errorMessage":"client_id is required","messagePattern":"client_id is required","errorType":"http","errorClass":"BadRequest","httpStatus":400,"severity":"error","filePath":"api/controllers/console/auth/oauth_server.py","lineNumber":84,"sourceCode":"\nregister_schema_models(console_ns, OAuthClientPayload, OAuthProviderRequest, OAuthTokenRequest)\nregister_response_schema_models(\n    console_ns,\n    OAuthProviderAccountResponse,\n    OAuthProviderAppResponse,\n    OAuthProviderAuthorizeResponse,\n    OAuthProviderTokenResponse,\n)\n\n\ndef oauth_server_client_id_required[T, **P, R](\n    view: Callable[Concatenate[T, OAuthProviderApp, P], R],\n) -> Callable[Concatenate[T, P], R]:\n    @wraps(view)\n    def decorated(self: T, *args: P.args, **kwargs: P.kwargs) -> R:\n        json_data = request.get_json()\n        if json_data is None:\n            raise BadRequest(\"client_id is required\")\n\n        payload = OAuthClientPayload.model_validate(json_data)\n        client_id = payload.client_id\n\n        oauth_provider_app = OAuthServerService.get_oauth_provider_app(client_id)\n        if not oauth_provider_app:\n            raise NotFound(\"client_id is invalid\")\n\n        return view(self, oauth_provider_app, *args, **kwargs)\n\n    return decorated\n\n\ndef oauth_server_access_token_required[T, **P, R](\n    view: Callable[Concatenate[T, OAuthProviderApp, Account, P], R],\n) -> Callable[Concatenate[T, OAuthProviderApp, P], R | ResponseReturnValue]:\n    @wraps(view)\n    def decorated(","sourceCodeStart":66,"sourceCodeEnd":102,"githubUrl":"https://github.com/langgenius/dify/blob/ef8544b173fd6cd7a8e71df2cab576e52bebbfbc/api/controllers/console/auth/oauth_server.py#L66-L102","documentation":"Flask BadRequest (HTTP 400) raised by the oauth_server_client_id_required decorator at oauth_server.py:84 when request.get_json() returns None — i.e. the request body is empty, not JSON, or has the wrong Content-Type. It guards every OAuth-server endpoint that needs a client_id (POST /oauth/provider, /authorize, /token, /account). The message is 'client_id is required' even though the real cause is a missing/invalid JSON body.","triggerScenarios":"Calling any of the /console/api/oauth/provider* endpoints with an empty body, form-encoded body, or Content-Type other than application/json. request.get_json() returns None and the decorator raises before OAuthClientPayload is even parsed.","commonSituations":"OAuth client integration sends URL-encoded form data (common for standard OAuth token endpoints) instead of JSON; or a curl/test client omits the body entirely. Developers expect RFC 6749 form-post behavior but this server expects JSON.","solutions":["Send the request body as JSON with header Content-Type: application/json and include {\"client_id\": \"...\"}.","If integrating a standards-compliant OAuth client that posts form data, add an adapter to translate form fields to JSON before calling this endpoint.","Confirm the body is not empty — even valid JSON with a missing client_id would fail later at OAuthClientPayload.model_validate, not here.","Check for a proxy/middleware stripping the request body or Content-Type."],"exampleFix":"# before\ncurl -X POST $URL/oauth/provider -d 'client_id=abc'\n# after\ncurl -X POST $URL/oauth/provider -H 'Content-Type: application/json' -d '{\"client_id\":\"abc\"}'","handlingStrategy":"validation","validationCode":"// Ensure a JSON body with client_id before calling any /oauth/provider* endpoint.\nfunction buildBody(clientId, extra = {}) {\n  if (!clientId) throw new Error('client_id required');\n  return JSON.stringify({client_id: clientId, ...extra});\n}\nawait fetch('/console/api/oauth/provider', {\n  method: 'POST', headers: {'Content-Type': 'application/json'}, body: buildBody(cid)\n});","typeGuard":"function isJsonObject(v): v is Record<string, unknown> {\n  return typeof v === 'object' && v !== null;\n}","tryCatchPattern":"try {\n  await callOAuthServer(cid);\n} catch (e) {\n  if (/client_id is required/i.test(e.message)) {\n    throw new Error('Send a JSON body with Content-Type: application/json');\n  }\n  throw e;\n}","preventionTips":["Always send Content-Type: application/json to OAuth-server endpoints.","Never URL-form-encode; this server expects JSON unlike standard RFC 6749.","Assert the body is non-empty before sending."],"tags":["oauth-server","request-validation","json","content-type"],"backgroundTag":null,"analyzedSha":"ef8544b173fd6cd7a8e71df2cab576e52bebbfbc","analyzedAt":"2026-08-12T05:15:17.394Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}