cube-js/cube · error · Error
options.contextToApiScopes must be a function
Error message
options.contextToApiScopes must be a function
What it means
registerInterface requires contextToApiScopes to be a function that maps the security context to API scopes for the native SQL interface. If the property is missing or not a function, the interface cannot enforce API scoping, so it throws.
Source
Thrown at packages/cubejs-backend-native/js/index.ts:388
export const resetLogger = (logLevel: LogLevel): void => {
const native = loadNative();
native.resetLogger({ logLevel });
};
export const isFallbackBuild = (): boolean => {
const native = loadNative();
return native.isFallbackBuild();
};
export type SqlInterfaceInstance = { __typename: 'sqlinterfaceinstance' };
export const registerInterface = async (options: SQLInterfaceOptions): Promise<SqlInterfaceInstance> => {
if (typeof options !== 'object' && options == null) {
throw new Error('Argument options must be an object');
}
if (typeof options.contextToApiScopes !== 'function') {
throw new Error('options.contextToApiScopes must be a function');
}
if (typeof options.checkAuth !== 'function') {
throw new Error('options.checkAuth must be a function');
}
if (typeof options.checkSqlAuth !== 'function') {
throw new Error('options.checkSqlAuth must be a function');
}
if (typeof options.meta !== 'function') {
throw new Error('options.meta must be a function');
}
if (typeof options.stream !== 'function') {
throw new Error('options.stream must be a function');
}
View on GitHub (pinned to 7d981676b3)
Solutions
- Add a contextToApiScopes function to the options, e.g. (context) => context.apiScopes.
- Check spelling/casing of the property name in the options object.
- Ensure the options are built in code (not deserialized from JSON) so functions survive.
Example fix
// before
await registerInterface({ checkAuth, checkSqlAuth, meta, stream });
// after
await registerInterface({
contextToApiScopes: (context) => context.apiScopes ?? [],
checkAuth, checkSqlAuth, meta, stream
}); Defensive patterns
Strategy: validation
Validate before calling
if (typeof options.contextToApiScopes !== 'function') {
throw new Error('options.contextToApiScopes must be provided as a function');
} Type guard
function hasContextToApiScopes(o) {
return typeof o?.contextToApiScopes === 'function';
} Try / catch
try {
await registerInterface(options);
} catch (e) {
if (e.message === 'options.contextToApiScopes must be a function') {
console.error('Add contextToApiScopes: (context) => context.apiScopes to the options.');
} else throw e;
} Prevention
- Keep all six required callbacks in one factory function so none are forgotten.
- Do not pass options built from JSON — functions cannot survive serialization.
- Type the options object in TypeScript as SQLInterfaceOptions to catch missing fields at compile time.
When it happens
Trigger: Calling registerInterface() with an options object lacking a contextToApiScopes function, or supplying a non-function value (object, string, undefined).
Common situations: Following outdated docs/examples where the callback was optional or named differently; forgetting the callback when migrating to the native SQL planner; passing config from JSON where functions can't be serialized.
Related errors
- Argument options must be an object
- options.checkAuth must be a function
- options.checkSqlAuth must be a function
- options.meta must be a function
- options.stream must be a function
AI-assisted analysis of cube-js/cube@7d981676b3 (2026-09-02).
Data as JSON: /api/errors/afc05f489264792a.
Report an issue: GitHub.