cube-js/cube · error
A user-defined contextToApiScopes function returns a wrong s
Error message
A user-defined contextToApiScopes function returns a wrong scope: ${p} What it means
After confirming contextToApiScopes returns an array, Cube validates every element against the allowed scopes: 'graphql', 'meta', 'data', 'sql', 'jobs'. If the function returns an array containing any other string, this Error names the offending scope.
Source
Thrown at packages/cubejs-api-gateway/src/gateway.ts:2788
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 {
return this.contextToApiScopesDefFn();
}
};
}
protected async assertApiScope(View on GitHub (pinned to 7d981676b3)
Solutions
- Map your application roles onto the exact supported scopes: 'graphql', 'meta', 'data', 'sql', 'jobs'.
- Fix typos in scope names returned by the function (compare against the error message's offending value).
- Introduce an explicit role→scopes mapping object in your config instead of passing raw role strings.
- Add a unit test for contextToApiScopes asserting outputs are subsets of the allowed list.
Example fix
// before contextToApiScopes: (ctx) => [ctx.role], // 'admin' // after contextToApiScopes: (ctx) => ctx.role === 'admin' ? ['graphql', 'meta', 'data', 'sql', 'jobs'] : ['data'],
Defensive patterns
Strategy: validation
Validate before calling
const ALLOWED = ['graphql', 'meta', 'data', 'sql', 'jobs'];
function validateScopes(scopes) {
if (!Array.isArray(scopes)) throw new TypeError('must be array');
const bad = scopes.filter(s => !ALLOWED.includes(s));
if (bad.length) throw new Error(`Unknown scopes: ${bad.join(', ')}`);
return scopes;
} Type guard
const isApiScope = (s) => ['graphql','meta','data','sql','jobs'].includes(s);
function areValidScopes(v) {
return Array.isArray(v) && v.every(isApiScope);
} Try / catch
try {
await cubeApi.load(query);
} catch (e) {
if (/wrong scope/.test(e.message)) {
// fix the scope mapping in server config using the offending value in the message
}
throw e;
} Prevention
- Maintain an explicit ROLE_TO_SCOPES map using only the five allowed scope strings
- Never pass raw application role names through as scopes
- Unit-test the scope mapping against the allowed list on every config change
When it happens
Trigger: A custom contextToApiScopes returning values like 'read', 'write', 'admin', 'all', or pluralized/typo'd names ('datas', 'metas') that are not among the five permitted scope strings.
Common situations: Mapping app-level permissions/roles directly into scopes without translating them to Cube's scope vocabulary; inventing custom scopes expecting them to be honored; typos after upgrading Cube where the allowed list differs from what an old example showed.
Related errors
- A user-defined contextToApiScopes function returns an incons
- Variable "${value.name.value}" is not defined
- Value "${input}" is not valid for ${envName}. ${description}
- Value "${input}" is not valid for ${envName}. Should be a po
- Value "${input}" is not valid for ${envName}. Should be lowe
AI-assisted analysis of cube-js/cube@7d981676b3 (2026-09-02).
Data as JSON: /api/errors/a9b5b93b6040908e.
Report an issue: GitHub.