cube-js/cube · error
A user-defined contextToApiScopes function returns an incons
Error message
A user-defined contextToApiScopes function returns an inconsistent type.
What it means
The user-supplied `contextToApiScopes` option must resolve to an array of API scope strings. If it returns null, undefined, or a non-array value (a string, object, Promise resolving to something else), the gateway throws this plain Error while computing the request's API scopes.
Source
Thrown at packages/cubejs-api-gateway/src/gateway.ts:2782
return {
securityContext: ctx.securityContext
};
};
}
protected createContextToApiScopesFn(
options: ApiGatewayOptions,
): ContextToApiScopesFn {
return options.contextToApiScopes
? async (securityContext?: any, defaultApiScopes?: ApiScopes[]) => {
const scopes = options.contextToApiScopes &&
await options.contextToApiScopes(
securityContext,
defaultApiScopes,
);
if (!scopes || !Array.isArray(scopes)) {
throw new Error(
'A user-defined contextToApiScopes function returns an inconsistent type.'
);
} else {
scopes.forEach((p) => {
if (['graphql', 'meta', 'data', 'sql', 'jobs'].indexOf(p) === -1) {
throw new Error(
`A user-defined contextToApiScopes function returns a wrong scope: ${p}`
);
}
});
}
return scopes;
}
: async () => {
const defaultApiScope = getEnv('defaultApiScope');
if (defaultApiScope) {
return defaultApiScope;
} else {View on GitHub (pinned to 7d981676b3)
Solutions
- Always return an array from contextToApiScopes, e.g. `return ['data']` instead of `return 'data'`.
- Ensure every code branch in the function returns a value (add a default branch returning defaultApiScopes).
- Await any async lookups (roles DB queries) before returning so the function doesn't return a pending promise mishandled as falsy.
- Validate the return shape at the end: throw your own descriptive error if the computed scopes aren't an array.
Example fix
// before contextToApiScopes: (ctx) => ctx.role === 'admin' ? ['data','meta','sql'] : 'data', // after contextToApiScopes: async (ctx, defaultApiScopes) => ctx.role === 'admin' ? ['data', 'meta', 'sql'] : [...defaultApiScopes],
Defensive patterns
Strategy: validation
Validate before calling
async function safeContextToApiScopes(ctx, defaultApiScopes) {
const scopes = await myContextToApiScopes(ctx, defaultApiScopes);
if (!Array.isArray(scopes)) throw new TypeError('contextToApiScopes must return an array');
return scopes;
} Type guard
function isApiScopesArray(v) {
return Array.isArray(v) && v.every(s => typeof s === 'string');
} Try / catch
try {
const scopes = await contextToApiScopes(ctx, defaults);
} catch (e) {
if (/inconsistent type/.test(e.message)) {
// fall back to defaults and alert: contextToApiScopes returned non-array
}
throw e;
} Prevention
- Add a unit test asserting your contextToApiScopes always returns an array for every role
- Return [...defaultApiScopes] on any fall-through branch
- Use TypeScript ApiScopes[] as the declared return type to catch shape bugs at compile time
When it happens
Trigger: A custom contextToApiScopes(securityContext, defaultApiScopes) implementation returning a single string like 'data', returning undefined on a code path (e.g. missing role branch), or forgetting `await`/`return` inside the async function.
Common situations: Copying an example but short-circuiting with a conditional that falls through; refactoring the function to return a Set or object instead of an array; returning defaultApiScopes directly when it happens to be a falsy/unsupported value.
Related errors
- A user-defined contextToApiScopes function returns a wrong s
- API scope is missing: ${scope}
- Variable "${value.name.value}" is not defined
- Unload is not configured. Please define CUBEJS_AWS_S3_OUTPUT
- Export bucket is not configured.
AI-assisted analysis of cube-js/cube@7d981676b3 (2026-09-02).
Data as JSON: /api/errors/a958801db00c27af.
Report an issue: GitHub.