langgenius/dify · error · NotFound
client_id is invalid
Error message
client_id is invalid
What it means
Flask NotFound (HTTP 404) raised at oauth_server.py:91 by the oauth_server_client_id_required decorator after OAuthServerService.get_oauth_provider_app(client_id) returns a falsy value — no OAuthProviderApp row matches the supplied client_id. The body was valid JSON and parsed into OAuthClientPayload, but the client_id does not correspond to a registered provider app.
Source
Thrown at api/controllers/console/auth/oauth_server.py:91
OAuthProviderTokenResponse,
)
def oauth_server_client_id_required[T, **P, R](
view: Callable[Concatenate[T, OAuthProviderApp, P], R],
) -> Callable[Concatenate[T, P], R]:
@wraps(view)
def decorated(self: T, *args: P.args, **kwargs: P.kwargs) -> R:
json_data = request.get_json()
if json_data is None:
raise BadRequest("client_id is required")
payload = OAuthClientPayload.model_validate(json_data)
client_id = payload.client_id
oauth_provider_app = OAuthServerService.get_oauth_provider_app(client_id)
if not oauth_provider_app:
raise NotFound("client_id is invalid")
return view(self, oauth_provider_app, *args, **kwargs)
return decorated
def oauth_server_access_token_required[T, **P, R](
view: Callable[Concatenate[T, OAuthProviderApp, Account, P], R],
) -> Callable[Concatenate[T, OAuthProviderApp, P], R | ResponseReturnValue]:
@wraps(view)
def decorated(
self: T, oauth_provider_app: OAuthProviderApp, *args: P.args, **kwargs: P.kwargs
) -> R | ResponseReturnValue:
if not isinstance(oauth_provider_app, OAuthProviderApp):
raise BadRequest("Invalid oauth_provider_app")
authorization_header = request.headers.get("Authorization")
if not authorization_header:View on GitHub (pinned to ef8544b173)
Solutions
- Verify the client_id against the OAuth provider apps table / admin console and use the correct one for this environment.
- If the app was deleted or rotated, register a new OAuthProviderApp and update the client configuration.
- Confirm there is no leading/trailing whitespace or encoding issue in the client_id value.
- Check that the deployment hosting the endpoint actually has the provider app seeded (env/config mismatch across replicas).
Defensive patterns
Strategy: validation
Validate before calling
// Validate the client_id is registered before first use; cache the lookup.
const apps = await listOAuthProviderApps();
if (!apps.find(a => a.client_id === cid)) {
throw new Error('Unknown client_id for this environment');
} Type guard
function isValidClientId(id: string): boolean {
return typeof id === 'string' && id.trim().length > 0 && /^[A-Za-z0-9_-]+$/.test(id);
} Try / catch
try {
await callOAuthServer(cid);
} catch (e) {
if (e.status === 404 && /client_id is invalid/i.test(e.message)) {
refreshProviderAppConfig();
} else throw e;
} Prevention
- Store client_id per environment to avoid staging/prod mix-ups.
- Re-verify the id after any app rotation.
- Strip whitespace when copying the id.
When it happens
Trigger: POST to any /console/api/oauth/provider* endpoint with a JSON body whose client_id is not registered, was deleted, or has a typo. get_oauth_provider_app returns None/empty -> NotFound.
Common situations: Client copied the wrong client_id (e.g. from a different environment), the provider app was rotated/revoked, or the app was never created. Also happens when dev/staging/prod client_ids are mixed up.
Related errors
- export response missing data field
- reconnect stream body missing
- server_4xx_other
- unknown
- usage_missing_arg
AI-assisted analysis of langgenius/dify@ef8544b173 (2026-08-12).
Data as JSON: /api/errors/6c42831e883d5923.
Report an issue: GitHub.