RocketChat/Rocket.Chat · warning
Invalid OAuth client
Error message
Invalid OAuth client
What it means
useOAuthAppQuery's queryFn throws 'Invalid OAuth client' as a first guard when clientId is undefined — the hook cannot call GET /v1/oauth-apps.get without it. Because react-query executes queryFn as soon as the query mounts (unless disabled), an absent clientId turns into a failed query rather than a skipped one.
Source
Thrown at apps/meteor/client/views/oauth/hooks/useOAuthAppQuery.ts:19
import type { IOAuthApps } from '@rocket.chat/core-typings';
import { useEndpoint } from '@rocket.chat/ui-contexts';
import type { UseQueryOptions } from '@tanstack/react-query';
import { useQuery } from '@tanstack/react-query';
type UseOAuthAppQueryOptions = Omit<
UseQueryOptions<IOAuthApps, unknown, IOAuthApps, readonly ['oauth-app', { readonly clientId: string | undefined }]>,
'queryKey' | 'queryFn'
>;
export const useOAuthAppQuery = (clientId: string | undefined, options?: UseOAuthAppQueryOptions) => {
const getOAuthApp = useEndpoint('GET', '/v1/oauth-apps.get');
return useQuery({
queryKey: ['oauth-app', { clientId }] as const,
queryFn: async () => {
if (!clientId) {
throw new Error('Invalid OAuth client');
}
const { oauthApp } = await getOAuthApp({ clientId });
return {
...oauthApp,
_createdAt: new Date(oauthApp._createdAt),
_updatedAt: new Date(oauthApp._updatedAt),
};
},
...options,
});
};
View on GitHub (pinned to b2c16d5842)
Solutions
- Pass enabled: Boolean(clientId) through options so the query waits for the id.
- Fix the source of clientId (route param name, link generation) so it is present.
- Render a loading/empty state while clientId is undefined.
Example fix
// before
const { data } = useOAuthAppQuery(clientId);
// after
const { data } = useOAuthAppQuery(clientId, {
enabled: Boolean(clientId),
}); Defensive patterns
Strategy: validation
Validate before calling
useOAuthAppQuery(clientId, {
enabled: Boolean(clientId), // queryFn never runs with undefined
}); Type guard
const hasClientId = (v: string | undefined): v is string => Boolean(v && v.length > 0);
Prevention
- Always pass enabled: Boolean(clientId) for id-dependent queries.
- Validate route params before rendering id-driven components.
- Show a loading skeleton while the param resolves.
When it happens
Trigger: Rendering the OAuth app admin/route that uses this hook without a clientId route param (bad link, missing parameter), or passing undefined during a parent's loading state while the query is still enabled.
Common situations: Deep links or bookmarks to /oauth/... missing the client id segment; refactors renaming the route param; component reused in contexts where the id arrives asynchronously.
Related errors
- The command is not currently disabled: "${cmd}"
- The user for app ${appId} is not registered.
- FileUpload_Error
- error-parameter-required
- error-challenge-not-found
AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18).
Data as JSON: /api/errors/052406d7a54a33ff.
Report an issue: GitHub.