cube-js/cube · error
No cancel handler for
Error message
No cancel handler for ${queryHandler} What it means
processCancel looks up a cancel handler registered in this.cancelHandlers keyed by the query's queryHandler name; if none was registered for that handler it throws instead of silently ignoring the cancel request. Only handlers explicitly registered via addCancelHandler (or the defaults like 'query') can be cancelled.
Solutions
- Register a cancel handler for the queryHandler name via queue.addCancelHandler(name, fn)
- Only call cancelQuery for queries using the standard cancellable 'query' handler
- Fix typos in the queryHandler name so it matches a registered handler
Example fix
// before
await queue.cancelQuery(queryWithCustomHandler); // throws: no cancel handler
// after
queue.addCancelHandler('myCustomHandler', async (q) => {
await customRegistry.cancel(q.queryKey);
});
await queue.cancelQuery(queryWithCustomHandler); Defensive patterns
Strategy: validation
Validate before calling
if (!queue.cancelHandlers?.[query.queryHandler]) { console.warn(`Cancel unsupported for handler ${query.queryHandler}`); return false; } Type guard
function isCancelable(q) { return typeof q.queryHandler === 'string' && q.queryHandler in queue.cancelHandlers; } Try / catch
try { await queue.cancelQuery(query); } catch (e) { if (e.message.startsWith('No cancel handler for')) return false; throw e; } Prevention
- Register addCancelHandler for every custom query handler
- Only cancel queries using the standard 'query' handler
- Check the cancelHandlers map before issuing cancellation
When it happens
Trigger: Calling cancelQuery / processCancel for a query whose queryHandler has no entry in cancelHandlers — e.g. custom handlers ('stream', pre-aggregation build handlers, user-registered names) that were never registered with addCancelHandler.
Common situations: Attempting to cancel a pre-aggregation build or streaming query through the standard cancel API; registering a custom query handler but forgetting to register its cancel counterpart; typos in handler names.
Related errors
- Streaming queries to Cube Store aren't supported
- aborted
- CancelToken was already canceled
- CubeSQL query was aborted
- Job has been canceled
AI-assisted analysis of cube-js/cube@7d981676b3 (2026-09-02).
Data as JSON: /api/errors/274b2691c9c84e93.
Report an issue: GitHub.
Appendix: source
Thrown at packages/cubejs-query-orchestrator/src/orchestrator/QueryQueue.ts:1076
queryKey: query.queryKey,
requestId: query.requestId,
error: (e.stack || e).toString(),
queuePrefix: this.redisQueuePrefix
});
} finally {
this.queueDriver.release(queueConnection);
}
}
/**
* Processing cancel query flow.
*/
protected async processCancel(query: QueryDef, queueId: QueueId | null) {
const { queryHandler } = query;
try {
if (!this.cancelHandlers[queryHandler]) {
throw new Error(`No cancel handler for ${queryHandler}`);
}
await this.cancelHandlers[queryHandler](query);
} catch (e: any) {
this.logger('Error while cancel', {
queueId,
queryKey: query.queryKey,
error: e.stack || e,
queuePrefix: this.redisQueuePrefix,
requestId: query.requestId
});
}
}
protected redisHash(queryKey: QueryKey): QueryKeyHash {
return this.queueDriver.redisHash(queryKey);
}
}View on GitHub (pinned to 7d981676b3)