github/copilot-sdk · error
No canvas registered with id
Error message
No canvas registered with id "${params.canvasId}" What it means
The session's client canvas API open() looks up the requested canvasId in the session's registered canvases map. If no canvas with that id was registered (via session canvas registration), the RPC is rejected with this error rather than returning undefined.
Solutions
- Verify the canvasId exactly matches the id used at registration.
- Register the canvas on the session (canvases.set / registration API) before the client opens it.
- Ensure the client is joined to the session that actually holds the registration.
Example fix
// before
await canvas.open({ canvasId: "main-canvas " }); // trailing space, unregistered
// after
session.registerCanvas({ canvasId: "main-canvas", /* ... */ });
await canvas.open({ canvasId: "main-canvas" }); Defensive patterns
Strategy: validation
Validate before calling
const known = new Set(getRegisteredCanvasIds(session));
if (!known.has(canvasId)) throw new Error(`Canvas "${canvasId}" not registered on this session`); Try / catch
try { await canvas.open({ canvasId }); } catch (e) { if (String(e.message).startsWith('No canvas registered')) await registerCanvas({ canvasId }) .then(() => canvas.open({ canvasId })); else throw e; } Prevention
- Source canvasId from a shared constant, not string literals.
- Register all canvases before the client sends open requests.
- Re-register canvases on session reconnect.
When it happens
Trigger: A client calls canvas.open({ canvasId }) with an id never registered on the session, an id registered on a different session, or after the canvas registration was removed.
Common situations: Typo or stale canvas id hard-coded in the client; reconnecting to a new session that lacks the previous registration; registration happening after the client's first open attempt (race).
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- canvas_action_no_handler
- workingDirectory is not supported with…
- env is not supported with RuntimeConnection.forInProcess()…
- No session found for sessionId
- Copilot request response used after RPC connection closed.
AI-assisted analysis of github/copilot-sdk@cd8cf15dc3 (2026-09-09).
Data as JSON: /api/errors/1ebb9013652c5c70.
Report an issue: GitHub.
Appendix: source
Thrown at nodejs/src/session.ts:1394
*
* @param canvases - Canvases created via `createCanvas`, or undefined to clear all canvases
* @internal Called by the SDK when creating/resuming a session with `canvases`.
*/
registerCanvases(canvases?: Canvas[]): void {
this.canvases.clear();
if (!canvases || canvases.length === 0) {
delete this.clientSessionApis.canvas;
return;
}
for (const canvas of canvases) {
this.canvases.set(canvas.declaration.id, canvas);
}
const self = this;
this.clientSessionApis.canvas = {
async open(params) {
const canvas = self.canvases.get(params.canvasId);
if (!canvas) throw new Error(`No canvas registered with id "${params.canvasId}"`);
try {
return (await canvas.open(params)) ?? {};
} catch (error) {
throw toCanvasRpcError(error);
}
},
async close(params) {
const canvas = self.canvases.get(params.canvasId);
if (!canvas) throw new Error(`No canvas registered with id "${params.canvasId}"`);
try {
if (canvas.onClose) {
await canvas.onClose(params);
}
} catch (error) {
throw toCanvasRpcError(error);
}
},
async invoke(params) {View on GitHub (pinned to cd8cf15dc3)