Skip to content

Conversation

@code-yeongyu
Copy link
Owner

@code-yeongyu code-yeongyu commented Feb 11, 2026

Fixes #1746

Problem

Three tool.execute.after hooks crash with TypeError: undefined is not an object (evaluating 'output.output.toLowerCase') when MCP tools return results where output.output is undefined. This breaks ALL external MCP tools since v3.5.0.

Affected Hooks

File Line Crash
comment-checker/hook.ts L95 output.output.toLowerCase()
edit-error-recovery/hook.ts L47 output.output.toLowerCase()
task-resume-info/hook.ts L24-31 .startsWith(), .includes(), .trimEnd()

Fix

Added if (!output.output || typeof output.output !== "string") return guard at the top of each affected hook handler.

Testing (TDD)

  • Tests for each hook with undefined output.output — all pass
  • Existing tests unaffected

Related


Summary by cubic

Prevent crashes in tool.execute.after hooks caused by undefined output from MCP tools, restoring compatibility with external tools. Fixes #1746.

  • Bug Fixes
    • Added string guards and early returns for output.output in comment-checker, edit-error-recovery, and task-resume-info.
    • Added tests to cover undefined output in all three hooks.

Written for commit 8b44d3b. Summary will update on new commits.

Three hooks crashed with TypeError when MCP tools returned results where
output.output is undefined. Added type guards to all affected hooks:

- comment-checker/hook.ts: guard before toLowerCase()
- edit-error-recovery/hook.ts: guard before toLowerCase()
- task-resume-info/hook.ts: guard before startsWith()/includes()/trimEnd()
- Added test for undefined output.output in edit-error-recovery

Fixes #1746
Copy link

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 7 files

Confidence score: 4/5

  • The main concern is in src/hooks/comment-checker/hook.ts: an early return on missing output.output can skip comment checks for write/edit/apply_patch cases, which could let unchecked changes through.
  • This is a moderate-risk behavioral gap rather than a crash, so the PR still looks safe to merge with minor caution.
  • Pay close attention to src/hooks/comment-checker/hook.ts - ensure missing output is handled without skipping comment checks.
Prompt for AI agents (all issues)

Check if these issues are valid — if so, understand the root cause of each and fix them.


<file name="src/hooks/comment-checker/hook.ts">

<violation number="1" location="src/hooks/comment-checker/hook.ts:92">
P2: Early-returning on missing output.output prevents the hook from running comment checks for write/edit/apply_patch cases where tools omit output.output. Instead of returning, coerce to an empty string so the hook can still process metadata/pending calls.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

): Promise<void> => {
debugLog("tool.execute.after:", { tool: input.tool, callID: input.callID })

if (!output.output || typeof output.output !== "string") return
Copy link

@cubic-dev-ai cubic-dev-ai bot Feb 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Early-returning on missing output.output prevents the hook from running comment checks for write/edit/apply_patch cases where tools omit output.output. Instead of returning, coerce to an empty string so the hook can still process metadata/pending calls.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/hooks/comment-checker/hook.ts, line 92:

<comment>Early-returning on missing output.output prevents the hook from running comment checks for write/edit/apply_patch cases where tools omit output.output. Instead of returning, coerce to an empty string so the hook can still process metadata/pending calls.</comment>

<file context>
@@ -89,6 +89,8 @@ export function createCommentCheckerHooks(config?: CommentCheckerConfig) {
     ): Promise<void> => {
       debugLog("tool.execute.after:", { tool: input.tool, callID: input.callID })
 
+      if (!output.output || typeof output.output !== "string") return
+
       const toolLower = input.tool.toLowerCase()
</file context>
Suggested change
if (!output.output || typeof output.output !== "string") return
if (typeof output.output !== "string") output.output = ""
Fix with Cubic

@code-yeongyu
Copy link
Owner Author

Closing in favor of #1756.

#1756 uses ?? "" (nullish coalescing) instead of early return, which is safer — early return here skips comment checks entirely for write/edit cases where output.output is undefined (cubic also flagged this as P2). #1756 also covers the atlas hook fix and has more comprehensive tests (101-line task-resume-info suite). cubic gave it 5/5 + auto-approve vs 4/5 here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Unguarded output.output access in tool.execute.after hooks crashes all MCP tools

1 participant