fix(hooks): guard against undefined output.output in tool.execute.after hooks #1727
+127
−8
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Summary
Guard against
undefinedoutput.outputin all 14tool.execute.afterhooks and injectors that access the field.MCP tool results (e.g. Slack, Toggl) don't populate
output.outputas a string, causing:.toLowerCase()or.startsWith()onundefined"undefined"string corruption in hooks that use+=(producing"undefined\n\nSome reminder")Root Cause
The
tool.execute.afterhook fires for all tool calls, including MCP tools. The hook type signature declaresoutput: { output: string }, but MCP tool results don't always populate this field. Many hooks accessoutput.outputwithout null-checking first.Two existing hooks already guarded against this:
empty-task-response-detectorusesoutput.output?.trim() ?? ""tool-output-truncatorusedtypeof output.output !== 'string'The rest did not, and the codebase was inconsistent.
Fix
Add
output.output == nullearly-return guard to everytool.execute.afterhandler that accessesoutput.output. This:== null) to catch bothnullandundefinedtypeof !== 'string'check intool-output-truncatorto matchHooks fixed
comment-checker.toLowerCase()on undefinededit-error-recovery.toLowerCase()on undefinededitonly)task-resume-info.startsWith()on undefinedtask/call_omo_agent)delegate-task-retrytaskonly)context-window-monitorundefined +=task-reminderundefined +=claude-code-hooks handlercategory-skill-reminderundefined +=agent-usage-reminderundefined +=interactive-bash-sessionundefined +=interactive_bash)directory-readme-injectorundefined +=read/glob/grep)directory-agents-injectorundefined +=read/glob/grep)rules-injectorundefined +=read/glob/grep)tool-output-truncatorTesting
file://plugin path in OpenCode configconversations_add_messageandchannels_listcalls succeed after fix (previously all Slack MCP calls returned TypeError)output.outputis nullish