cube-js/cube · error · Error
options.stream must be a function
Error message
options.stream must be a function
What it means
registerInterface requires a stream function used to stream query results to SQL clients through the native interface. If options.stream is not a function, results cannot be streamed, so registration throws.
Source
Thrown at packages/cubejs-backend-native/js/index.ts:404
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');
}
if (typeof options.sqlApiLoad !== 'function') {
throw new Error('options.sqlApiLoad must be a function');
}
if (typeof options.sqlGenerators !== 'function') {
throw new Error('options.sqlGenerators must be a function');
}
if (typeof options.sql !== 'function') {
throw new Error('options.sql must be a function');
}
const native = loadNative();
return native.registerInterface({
...options,
contextToApiScopes: wrapNativeFunctionWithChannelCallback(options.contextToApiScopes),View on GitHub (pinned to 7d981676b3)
Solutions
- Provide a stream function that executes the query and streams rows back, delegating to your query orchestrator.
- Pass the same streaming handler used by the REST/WS API layer.
- Verify the handler is referenced, not invoked, when constructing options.
Example fix
// before
await registerInterface({ contextToApiScopes, checkAuth, checkSqlAuth, meta });
// after
await registerInterface({
contextToApiScopes, checkAuth, checkSqlAuth, meta,
stream: async (context, query) => orchestratorApi.executeQuery(context, query),
sqlApiLoad
}); Defensive patterns
Strategy: validation
Validate before calling
if (typeof options.stream !== 'function') {
throw new Error('options.stream must be provided as a function');
} Type guard
function hasStream(o) {
return typeof o?.stream === 'function';
} Try / catch
try {
await registerInterface(options);
} catch (e) {
if (e.message === 'options.stream must be a function') {
console.error('Provide stream: async (context, query) => orchestratorApi.executeQuery(context, query).');
} else throw e;
} Prevention
- Wire the same executeQuery/streaming handler your REST/WS API uses.
- Create the options object via a single factory listing all required callbacks (contextToApiScopes, checkAuth, checkSqlAuth, meta, stream, sqlApiLoad).
- Add a startup assertion that validates every callback type before registerInterface runs.
When it happens
Trigger: Calling registerInterface() with an options object whose stream property is missing or not a function.
Common situations: Building the native SQL interface without a results-streaming handler; confusing the required stream callback with Node stream utilities; copy-paste omitting stream while including sqlApiLoad.
Related errors
- options.contextToApiScopes must be a function
- options.checkAuth must be a function
- options.checkSqlAuth must be a function
- options.meta must be a function
- Argument options must be an object
AI-assisted analysis of cube-js/cube@7d981676b3 (2026-09-02).
Data as JSON: /api/errors/26953b495bdb9859.
Report an issue: GitHub.