{"record":{"id":"e2e85060e614b36a","repo":"github/copilot-sdk","slug":"canvas-action-no-handler","errorCode":"canvas_action_no_handler","errorMessage":"No handler implemented for this canvas action","messagePattern":"No handler implemented for this canvas action","errorType":"error_code","errorClass":"CanvasError","httpStatus":null,"severity":"error","filePath":"nodejs/src/session.ts","lineNumber":1417,"sourceCode":"                }\n            },\n            async close(params) {\n                const canvas = self.canvases.get(params.canvasId);\n                if (!canvas) throw new Error(`No canvas registered with id \"${params.canvasId}\"`);\n                try {\n                    if (canvas.onClose) {\n                        await canvas.onClose(params);\n                    }\n                } catch (error) {\n                    throw toCanvasRpcError(error);\n                }\n            },\n            async invoke(params) {\n                const canvas = self.canvases.get(params.canvasId);\n                if (!canvas) throw new Error(`No canvas registered with id \"${params.canvasId}\"`);\n                const handler = canvas.actionHandlers.get(params.actionName);\n                if (!handler) {\n                    throw new CanvasError(\n                        \"canvas_action_no_handler\",\n                        \"No handler implemented for this canvas action\"\n                    );\n                }\n                try {\n                    return (await handler(params)) as CanvasActionInvokeResult;\n                } catch (error) {\n                    throw toCanvasRpcError(error);\n                }\n            },\n        };\n    }\n\n    /**\n     * Registers factory closures and reverse-RPC handlers for this session.\n     *\n     * @param factories - Factory handles declared by the joining extension.\n     * @internal Called by the SDK when an extension joins a session.","sourceCodeStart":1399,"sourceCodeEnd":1435,"githubUrl":"https://github.com/github/copilot-sdk/blob/cd8cf15dc3f9e762615790aaed0a771a0f392755/nodejs/src/session.ts#L1399-L1435","documentation":"When invoke() finds the canvas but no handler is registered under actionHandlers for params.actionName, it throws a CanvasError with code canvas_action_no_handler. The session distinguishes \"unknown canvas\" from \"canvas exists but doesn't implement the action\".","triggerScenarios":"canvas.invoke({ canvasId, actionName }) where the canvas is registered but its actionHandlers map lacks actionName — typo'd action name, handler not implemented, or handler registered on a different canvas.","commonSituations":"Client shipped a new action before the canvas implementation registered it; version mismatch between client and session code; singular/plural or casing mismatch in action names.","solutions":["Add the missing entry to the canvas's actionHandlers map.","Fix the actionName spelling/casing to match a registered handler.","Update client and server sides to the same version so declared and implemented actions agree."],"exampleFix":"// before\nregisterCanvas({ canvasId: \"c1\", actionHandlers: {} });\nawait canvas.invoke({ canvasId: \"c1\", actionName: \"export\" });\n// after\nregisterCanvas({ canvasId: \"c1\", actionHandlers: { export: async (p) => ({}) } });","handlingStrategy":"validation","validationCode":"const handlers = getActionHandlers(canvasId);\nif (!handlers?.[actionName]) throw new Error(`Canvas \"${canvasId}\" has no handler for \"${actionName}\"`);","typeGuard":null,"tryCatchPattern":"try { await canvas.invoke({ canvasId, actionName }); } catch (e) { if (e?.code === 'canvas_action_no_handler') console.error(`Implement handler \"${actionName}\" on canvas \"${canvasId}\"`); else throw e; }","preventionTips":["Define action names in a shared union type/action map used by both sides.","Register a default/fallback handler for unsupported actions.","Keep client action catalogs and canvas actionHandlers in sync via a single source of truth."],"tags":["canvas","handler","rpc"],"backgroundTag":"method-not-implemented","analyzedSha":"cd8cf15dc3f9e762615790aaed0a771a0f392755","analyzedAt":"2026-09-09T18:32:31.973Z","contentChangedAt":"2026-09-09T18:32:31.973Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}