{"record":{"id":"b847605be331816d","repo":"github/copilot-sdk","slug":"invalid-hooks-invoke-payload","errorCode":null,"errorMessage":"Invalid hooks invoke payload","messagePattern":"Invalid hooks invoke payload","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nodejs/src/client.ts","lineNumber":3240,"sourceCode":"\n        const response = await session._handleAutoModeSwitchRequest({\n            errorCode: params.errorCode,\n            retryAfterSeconds: params.retryAfterSeconds,\n        });\n        return { response };\n    }\n\n    private async handleHooksInvoke(params: {\n        sessionId: string;\n        hookType: string;\n        input: unknown;\n    }): Promise<{ output?: unknown }> {\n        if (\n            !params ||\n            typeof params.sessionId !== \"string\" ||\n            typeof params.hookType !== \"string\"\n        ) {\n            throw new Error(\"Invalid hooks invoke payload\");\n        }\n\n        const session = this.sessions.get(params.sessionId);\n        if (!session) {\n            throw new Error(`Session not found: ${params.sessionId}`);\n        }\n\n        const output = await session._handleHooksInvoke(params.hookType, params.input);\n        return { output };\n    }\n\n    private async handleSystemMessageTransform(params: {\n        sessionId: string;\n        sections: Record<string, { content: string }>;\n    }): Promise<{ sections: Record<string, { content: string }> }> {\n        if (\n            !params ||\n            typeof params.sessionId !== \"string\" ||","sourceCodeStart":3222,"sourceCodeEnd":3258,"githubUrl":"https://github.com/github/copilot-sdk/blob/cd8cf15dc3f9e762615790aaed0a771a0f392755/nodejs/src/client.ts#L3222-L3258","documentation":"CopilotClient throws this when the hooks-invoke handler receives params that are missing, lack a string sessionId, or lack a string hookType. hookType selects which registered hook to run, so the library refuses to proceed without it.","triggerScenarios":"Calling the hooks-invoke method with params null/undefined, sessionId not a string, or hookType missing/not a string (e.g. passing input object first or hookType undefined).","commonSituations":"Hook dispatcher built from config where the hook name key is misspelled; passing the whole hook config object as params instead of {sessionId, hookType, input}; dynamic hook names resolved to undefined at runtime.","solutions":["Ensure params = { sessionId: string, hookType: string, input?: unknown } with hookType matching a registered hook name.","Log the resolved hookType; fix the config/source producing undefined names.","Validate hook registration list against invoked names before dispatching.","Unwrap the payload if you are forwarding an enveloped event object."],"exampleFix":"// before\nawait client.handleHooksInvoke({ sessionId, hookType: cfg.hook?.name, input });\n// after\nconst hookType = cfg.hook?.name;\nif (typeof hookType !== \"string\") throw new Error(\"hook not configured\");\nawait client.handleHooksInvoke({ sessionId, hookType, input });","handlingStrategy":"validation","validationCode":"if (!params || typeof params.sessionId !== \"string\" || typeof params.hookType !== \"string\") {\n  throw new TypeError(\"hooks invoke requires string sessionId and hookType\");\n}","typeGuard":"function isHooksInvokeParams(p): p is { sessionId: string; hookType: string; input?: unknown } {\n  return typeof p === \"object\" && p !== null &&\n    typeof (p as any).sessionId === \"string\" && typeof (p as any).hookType === \"string\";\n}","tryCatchPattern":"try {\n  await client.handleHooksInvoke(params);\n} catch (e) {\n  if (e instanceof Error && e.message === \"Invalid hooks invoke payload\") {\n    // log configured hookType and skip this hook\n  }\n}","preventionTips":["Keep hook names in a typed constant union instead of free-form config strings.","Validate hook config at startup; fail fast on missing names.","Never pass the hook config object itself as the params payload."],"tags":["validation","payload","hooks","typescript"],"backgroundTag":"missing-required-argument","analyzedSha":"cd8cf15dc3f9e762615790aaed0a771a0f392755","analyzedAt":"2026-09-09T18:32:31.973Z","contentChangedAt":"2026-09-09T18:32:31.973Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}