mongodb/node-mongodb-native · error · MongoMissingCredentialsError
User provided OIDC callbacks must return a valid object with
Error message
User provided OIDC callbacks must return a valid object with an accessToken.
What it means
Thrown by the shared OIDC callback workflow when a user-provided OIDC callback returns a value that fails validation: it must be a non-null object containing accessToken, and may only contain the allowed properties accessToken, expiresInSeconds, refreshToken (src/cmap/auth/mongodb_oidc/callback_workflow.ts:146 and isCallbackResultInvalid at line 184). Extra unknown properties also invalidate the result. Surfaced as a MongoMissingCredentialsError.
Source
Thrown at src/cmap/auth/mongodb_oidc/callback_workflow.ts:147
token: string,
conversationId?: number
): Promise<void> {
await connection.command(
ns(credentials.source),
finishCommandDocument(token, conversationId),
undefined
);
}
/**
* Executes the callback and validates the output.
*/
protected async executeAndValidateCallback(params: OIDCCallbackParams): Promise<OIDCResponse> {
const result = await this.callback(params);
// Validate that the result returned by the callback is acceptable. If it is not
// we must clear the token result from the cache.
if (isCallbackResultInvalid(result)) {
throw new MongoMissingCredentialsError(CALLBACK_RESULT_ERROR);
}
return result;
}
/**
* Ensure the callback is only executed one at a time and throttles the calls
* to every 100ms.
*/
protected withLock(callback: OIDCCallbackFunction): OIDCCallbackFunction {
let lock: Promise<any> = Promise.resolve();
return async (params: OIDCCallbackParams): Promise<OIDCResponse> => {
// We do this to ensure that we would never return the result of the
// previous lock, only the current callback's value would get returned.
await lock;
lock = lock
.catch(() => null)
View on GitHub (pinned to 3366c21a63)
Solutions
- Ensure the callback resolves to an object with at least { accessToken: '<jwt string>' }.
- Strip any fields other than accessToken, expiresInSeconds (number), and refreshToken (string) from the returned object.
- Handle errors inside the callback and re-throw a meaningful Error rather than returning undefined.
- Double-check the return path: e.g. return { accessToken } not return { token: jwt }.
Example fix
// before
const callback = async (params) => {
const r = await fetch(idp);
return await r.json(); // returns {access_token, token_type, scope, ...}
};
// after
const callback = async (params) => {
const r = await fetch(idp);
const body = await r.json();
return {
accessToken: body.access_token,
expiresInSeconds: body.expires_in
};
}; Defensive patterns
Strategy: validation
Validate before calling
function validateOidcCallbackResult(r: unknown): void {
if (r == null || typeof r !== 'object') throw new Error('OIDC callback must return an object');
const allowed = new Set(['accessToken', 'expiresInSeconds', 'refreshToken']);
const obj = r as Record<string, unknown>;
if (typeof obj.accessToken !== 'string') throw new Error('OIDC callback result missing string accessToken');
for (const k of Object.keys(obj)) {
if (!allowed.has(k)) throw new Error(`OIDC callback returned disallowed property: ${k}`);
}
} Type guard
function isOidcResponse(r: unknown): r is { accessToken: string; expiresInSeconds?: number; refreshToken?: string } {
if (r == null || typeof r !== 'object') return false;
const o = r as Record<string, unknown>;
if (typeof o.accessToken !== 'string') return false;
return Object.getOwnPropertyNames(o).every(k => ['accessToken','expiresInSeconds','refreshToken'].includes(k));
} Try / catch
try {
await client.connect();
} catch (e) {
if (e instanceof MongoMissingCredentialsError && /OIDC callbacks must return/.test(e.message)) {
throw new Error('OIDC callback returned an invalid shape - ensure { accessToken: string } and no extra fields.');
}
throw e;
} Prevention
- Wrap custom OIDC callbacks to map the IdP response to exactly { accessToken, expiresInSeconds?, refreshToken? }.
- Never return undefined from a callback - throw an Error instead.
- Unit-test the callback against isOidcResponse before deploying.
When it happens
Trigger: A custom OIDC callback (configured via MongoClient auth mechanism properties 'OIDC_CALLBACK' or through a human workflow) returns undefined/null, returns an object without accessToken, returns accessToken of non-string type, or returns an object containing properties outside the allow-list.
Common situations: Callback returns the raw IdP response object verbatim (which may have extra fields like 'scope', 'token_type'), returns a Promise that resolves to undefined on a code path, or returns a nested token object like { token: {...} } instead of the flat shape.
Related errors
- TOKEN_RESOURCE must be set in the auth mechanism properties
- TOKEN_RESOURCE must be set in the auth mechanism properties
- No workflow provided to the OIDC auth provider.
- AuthContext must provide credentials.
- username and ENVIRONMENT '${this.mechanismProperties.ENVIRON
AI-assisted analysis of mongodb/node-mongodb-native@3366c21a63 (2026-08-04).
Data as JSON: /data/errors/c0bfef8a63962e41.json.
Report an issue: GitHub.