fix(hooks): add null guard for tool.execute.after output (#1054)
/review command and some Claude Code built-in commands trigger tool.execute.after hooks with undefined output, causing crashes when accessing output.metadata or output.output. Fixes #1035 Co-authored-by: sisyphus-dev-ai <sisyphus-dev-ai@users.noreply.github.com>
This commit is contained in:
@@ -66,6 +66,20 @@ describe("atlas hook", () => {
|
||||
})
|
||||
|
||||
describe("tool.execute.after handler", () => {
|
||||
test("should handle undefined output gracefully (issue #1035)", async () => {
|
||||
// #given - hook and undefined output (e.g., from /review command)
|
||||
const hook = createAtlasHook(createMockPluginInput())
|
||||
|
||||
// #when - calling with undefined output
|
||||
const result = await hook["tool.execute.after"](
|
||||
{ tool: "delegate_task", sessionID: "session-123" },
|
||||
undefined as unknown as { title: string; output: string; metadata: Record<string, unknown> }
|
||||
)
|
||||
|
||||
// #then - returns undefined without throwing
|
||||
expect(result).toBeUndefined()
|
||||
})
|
||||
|
||||
test("should ignore non-delegate_task tools", async () => {
|
||||
// #given - hook and non-delegate_task tool
|
||||
const hook = createAtlasHook(createMockPluginInput())
|
||||
|
||||
@@ -663,6 +663,11 @@ export function createAtlasHook(
|
||||
input: ToolExecuteAfterInput,
|
||||
output: ToolExecuteAfterOutput
|
||||
): Promise<void> => {
|
||||
// Guard against undefined output (e.g., from /review command - see issue #1035)
|
||||
if (!output) {
|
||||
return
|
||||
}
|
||||
|
||||
if (!isCallerOrchestrator(input.sessionID)) {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -237,6 +237,11 @@ export function createClaudeCodeHooksHook(
|
||||
input: { tool: string; sessionID: string; callID: string },
|
||||
output: { title: string; output: string; metadata: unknown }
|
||||
): Promise<void> => {
|
||||
// Guard against undefined output (e.g., from /review command - see issue #1035)
|
||||
if (!output) {
|
||||
return
|
||||
}
|
||||
|
||||
const claudeConfig = await loadClaudeHooksConfig()
|
||||
const extendedConfig = await loadPluginExtendedConfig()
|
||||
|
||||
|
||||
@@ -657,6 +657,10 @@ const OhMyOpenCodePlugin: Plugin = async (ctx) => {
|
||||
},
|
||||
|
||||
"tool.execute.after": async (input, output) => {
|
||||
// Guard against undefined output (e.g., from /review command - see issue #1035)
|
||||
if (!output) {
|
||||
return;
|
||||
}
|
||||
await claudeCodeHooks["tool.execute.after"](input, output);
|
||||
await toolOutputTruncator?.["tool.execute.after"](input, output);
|
||||
await contextWindowMonitor?.["tool.execute.after"](input, output);
|
||||
|
||||
Reference in New Issue
Block a user