Skip to content

Fix SessionEnd hook cancelled on exit by raising its 1s timeout (#8637) - #8640

Closed
ShuntaH wants to merge 1 commit into
manaflow-ai:mainfrom
ShuntaH:fix/session-end-hook-timeout
Closed

ShuntaH wants to merge 1 commit into
manaflow-ai:mainfrom
ShuntaH:fix/session-end-hook-timeout

Conversation

@ShuntaH

@ShuntaH ShuntaH commented Jul 22, 2026 •

Copy link
Copy Markdown

Summary

  • What changed? In the HOOKS_JSON that cmux-claude-wrapper injects via --settings, the SessionEnd hook's timeout is raised from 1 to 10 seconds. A short comment records why.
  • Why? On a normal session exit, Claude Code runs "${CMUX_CLAUDE_HOOK_CMUX_BIN:-cmux}" hooks claude session-end, which cold-starts the cmux binary and connects to the socket. That routinely takes longer than 1s, so Claude Code cancels the hook and prints SessionEnd hook [...] failed: Hook cancelled, leaving the session-end cleanup unrun. SessionEnd was the only synchronous hook with a 1s budget — every sibling uses 5–125s. The hook logic itself is fine; only the 1s ceiling was too tight. Fixes SessionEnd hook has timeout:1 → "Hook cancelled" on normal session exit #8637.

Kept the hook synchronous (not async) so cleanup completes before Claude tears down; only the timeout was too small.

Testing

  • bash -n Resources/bin/cmux-claude-wrapper — passes (syntax unchanged).
  • Extracted the edited HOOKS_JSON and parsed it with json.loads: valid JSON, SessionEnd command unchanged, timeout now 10.
  • Verified the hook command itself is not the problem — invoking it directly returns instantly:
    $ echo '{}' | "$CMUX_CLAUDE_HOOK_CMUX_BIN" hooks claude session-end
    OK      # exit 0
    
  • Not done: a full app rebuild (Xcode/Zig toolchain). This change is a data-value edit to the injected settings string, so behavior is exercised at runtime by Claude Code's hook timeout rather than by the Swift build. Happy to adjust if you'd prefer a different value or an async treatment.

Demo Video

N/A — no UI change; this is a hook timeout value in an injected settings string.

Checklist

  • I tested the change locally (hook command + JSON/syntax validated; full app rebuild not run — see Testing)
  • I added or updated tests for behavior changes (no test asserts this timeout; added an inline comment documenting the rationale instead)
  • I updated docs/changelog if needed (inline comment above the hook block)
  • I requested bot reviews after my latest commit
  • All code review bot comments are resolved
  • All human review comments are resolved

View with Codesmith Autofix with Codesmith
Need help on this PR? Tag /codesmith with what you need. Autofix is disabled.


Summary by cubic

Increase the SessionEnd hook timeout from 1s to 10s in cmux-claude-wrapper to stop cancellations on exit and ensure cleanup runs. The hook remains synchronous so teardown completes before Claude shuts down.

Written for commit d93aee5. Summary will update on new commits.

Review in cubic

Summary by CodeRabbit

  • Bug Fixes
    • Improved session cleanup reliability by allowing the session-end process up to 10 seconds to complete.
    • Prevented cleanup from being cancelled prematurely during shutdown.

The injected HOOKS_JSON gave the SessionEnd hook a 1s timeout while every
sibling synchronous hook uses 5-125s. On a normal session exit, cold-starting
the cmux binary to run `cmux hooks claude session-end` routinely exceeds 1s,
so Claude Code cancels it and prints:

    SessionEnd hook [...] failed: Hook cancelled

leaving the session-end cleanup unrun. The hook itself is fine (invoking it
manually returns OK instantly) -- only the 1s ceiling was too tight.

Raise the SessionEnd timeout to 10s to match the other synchronous hooks.
Kept synchronous rather than async so cleanup completes before teardown.

Fixes manaflow-ai#8637
@ShuntaH

ShuntaH commented Jul 22, 2026

Copy link
Copy Markdown
Author

@codex review
@coderabbitai review
@greptile-apps review
@cubic-dev-ai review

@chatgpt-codex-connector

Copy link
Copy Markdown

To use Codex here, create a Codex account and connect to github.

@coderabbitai

coderabbitai Bot commented Jul 22, 2026 •

Copy link
Copy Markdown

@ShuntaH: I’ll review the changes in #8640.

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@cubic-dev-ai

cubic-dev-ai Bot commented Jul 22, 2026

Copy link
Copy Markdown

@codex review
@coderabbitai review
@greptile-apps review
@cubic-dev-ai review

@ShuntaH I can't start this review because your workspace has reached its free monthly review limit. cubic has reviewed 241,631 of the 240,000 allowed lines of code this month. Reviews resume on 1 August 2026 (in 10 days). Paid plans include much higher monthly review limits. Upgrade now to resume reviews.

To help optimise your usage, you can tune cubic to get the most out of your usage limits:

Learn more →

@coderabbitai

coderabbitai Bot commented Jul 22, 2026 •

Copy link
Copy Markdown

Review Change Stack

Important

Review skipped

No new commits to review since the last review.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 1f6ef743-5e80-480c-ac79-e6e2755909de

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

The Claude wrapper’s SessionEnd hook timeout changes from 1 second to 10 seconds. Inline comments now describe synchronous cleanup, the shared timeout budget, and cold-start latency that could cancel teardown before completion.

Changes

SessionEnd hook timeout

Layer / File(s) Summary
Update SessionEnd cleanup timeout
Resources/bin/cmux-claude-wrapper
The SessionEnd hook timeout is set to 10 seconds, and comments document the synchronous cleanup budget and prior cancellation issue.

Estimated code review effort: 1 (Trivial) | ~3 minutes

Suggested reviewers: austinywang, lawrencecchen

🚥 Pre-merge checks | ✅ 25
✅ Passed checks (25 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly matches the main change: increasing the SessionEnd hook timeout to prevent cancellation on exit.
Description check ✅ Passed The description covers the summary, rationale, testing, demo video, and checklist, with only a minor template section missing.
Linked Issues check ✅ Passed The change directly addresses #8637 by raising SessionEnd timeout to 10s and keeping the hook synchronous.
Out of Scope Changes check ✅ Passed The patch is limited to the timeout value and explanatory comments, with no unrelated behavior changes.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Cmux Swift Actor Isolation ✅ Passed Diff only changes Resources/bin/cmux-claude-wrapper timeout/comment; no Swift sources or actor-isolation-sensitive code changed.
Cmux Swift Blocking Runtime ✅ Passed Only Resources/bin/cmux-claude-wrapper changed; no Swift files or blocking/runtime sync primitives were introduced, so the Swift-only rule doesn’t apply.
Cmux Browser Automation Off-Main ✅ Passed Diff only edits Resources/bin/cmux-claude-wrapper SessionEnd timeout/comment; no browser.* socket automation routing or tests were changed.
Cmux Expensive Synchronous Load ✅ Passed PR only tweaks a shell-wrapper hook timeout/comment; no Swift changes or synchronous agent-history loads on main actor/interactive paths.
Cmux Cache Substitution Correctness ✅ Passed The diff only raises a SessionEnd hook timeout in a shell wrapper; it doesn't swap a fresh read for a cached value in any persistence/history/snapshot path.
Cmux No Hacky Sleeps ✅ Passed The diff only raises SessionEnd’s hook timeout from 1s to 10s and updates comments; it adds no sleeps, timers, polling, or delayed dispatch.
Cmux Algorithmic Complexity ✅ Passed The diff only raises a hook timeout and updates comments; it adds no scans, joins, sorts, or batch work on scalable collections.
Cmux Swift Concurrency ✅ Passed PASS: HEAD changes only Resources/bin/cmux-claude-wrapper (a bash wrapper); no Swift files or legacy concurrency patterns were modified.
Cmux Swift @Concurrent ✅ Passed No Swift files or Swift concurrency annotations changed; the PR only edits a shell wrapper, so this rule is not applicable.
Cmux Swift Package Boundaries ✅ Passed Diff only changes Resources/bin/cmux-claude-wrapper, a shell wrapper/resource script; no Swift app-target logic or package-boundary violation is present.
Cmux Swiftpm Lockfiles ✅ Passed Only Resources/bin/cmux-claude-wrapper changed; no SwiftPM/Xcode/.gitignore/workflow or Package.resolved diffs were present.
Cmux Swift Logging ✅ Passed Diff only changes Resources/bin/cmux-claude-wrapper; no Swift sources or production logging statements are touched.
Cmux User-Facing Error Privacy ✅ Passed The diff only raises the SessionEnd timeout and adds a developer comment; it adds no user-visible error copy or leaked internal details.
Cmux Full Internationalization ✅ Passed PASS: the diff only changes a shell-hook timeout and inline comments/config tokens; no user-facing localized text or locale assets were touched.
Cmux Swiftui State Layout ✅ Passed Only Resources/bin/cmux-claude-wrapper changed; no SwiftUI state/layout code was introduced or modified.
Cmux Architecture Rethink ✅ Passed The diff only raises SessionEnd timeout 1→10 in a shell wrapper, with no added sleeps, observers, extra owners, or split lifecycle wiring.
Cmux Swift Auxiliary Window Close Shortcuts ✅ Passed PR only edits Resources/bin/cmux-claude-wrapper timeout JSON; no Swift window/window-controller code or cmuxAuxiliaryWindowIdentifiers changes.
Cmux Source Artifacts ✅ Passed Changed file is a hand-written shell wrapper config edit, which the rule explicitly allows as source/config rather than generated artifact.
Cmux No Test Or Debug Seam In Production Source ✅ Passed Only Resources/bin/cmux-claude-wrapper changed; no Swift production file under Sources/** was touched, so the seam rule is not applicable.
Cmux No Ambient Global State ✅ Passed Only a shell-script JSON timeout/comment changed; no new Swift top-level func/var/singleton or static-namespace surface was added.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@chatgpt-codex-connector

Copy link
Copy Markdown

To use Codex here, create a Codex account and connect to github.

@greptile-apps

greptile-apps Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR gives the synchronous Claude Code SessionEnd hook more time to finish cleanup. The main changes are:

  • Raises the SessionEnd timeout from 1 second to 10 seconds.
  • Documents why the hook remains synchronous.

Confidence Score: 4/5

The timeout test must be updated before merging.

  • The new timeout matches other synchronous lifecycle hooks.
  • The existing SessionEnd timeout assertion deterministically fails with the new value.

Resources/bin/cmux-claude-wrapper and tests/test_claude_wrapper_hooks.py

Important Files Changed

Filename Overview
Resources/bin/cmux-claude-wrapper Raises the SessionEnd hook timeout to 10 seconds, but leaves an existing test enforcing the old timeout range.

Reviews (1): Last reviewed commit: "Fix SessionEnd hook cancelled on exit by..." | Re-trigger Greptile

# on the workspaceAutoNaming setting via a socket probe, so it is a
# no-op when the feature is disabled.
HOOKS_JSON='{"preferredNotifChannel":"notifications_disabled","hooks":{"SessionStart":[{"matcher":"","hooks":[{"type":"command","command":"\"${CMUX_CLAUDE_HOOK_CMUX_BIN:-cmux}\" hooks claude session-start","timeout":10}]}],"Stop":[{"matcher":"","hooks":[{"type":"command","command":"\"${CMUX_CLAUDE_HOOK_CMUX_BIN:-cmux}\" hooks claude stop","timeout":10}]},{"matcher":"","hooks":[{"type":"command","command":"\"${CMUX_CLAUDE_HOOK_CMUX_BIN:-cmux}\" hooks feed --source claude","timeout":10,"async":true}]},{"matcher":"","hooks":[{"type":"command","command":"\"${CMUX_CLAUDE_HOOK_CMUX_BIN:-cmux}\" hooks claude auto-name","timeout":120,"async":true}]}],"SubagentStop":[{"matcher":"","hooks":[{"type":"command","command":"\"${CMUX_CLAUDE_HOOK_CMUX_BIN:-cmux}\" hooks feed --source claude","timeout":10,"async":true}]}],"SessionEnd":[{"matcher":"","hooks":[{"type":"command","command":"\"${CMUX_CLAUDE_HOOK_CMUX_BIN:-cmux}\" hooks claude session-end","timeout":1}]}],"Notification":[{"matcher":"","hooks":[{"type":"command","command":"\"${CMUX_CLAUDE_HOOK_CMUX_BIN:-cmux}\" hooks claude notification","timeout":10}]}],"UserPromptSubmit":[{"matcher":"","hooks":[{"type":"command","command":"\"${CMUX_CLAUDE_HOOK_CMUX_BIN:-cmux}\" hooks claude prompt-submit","timeout":10}]}],"PreToolUse":[{"matcher":"CronCreate","hooks":[{"type":"command","command":"\"${CMUX_CLAUDE_HOOK_CMUX_BIN:-cmux}\" hooks claude cron-create-guard","timeout":5}]},{"matcher":"","hooks":[{"type":"command","command":"\"${CMUX_CLAUDE_HOOK_CMUX_BIN:-cmux}\" hooks claude pre-tool-use","timeout":5,"async":true}]}],"PostToolUse":[{"matcher":"PushNotification","hooks":[{"type":"command","command":"\"${CMUX_CLAUDE_HOOK_CMUX_BIN:-cmux}\" hooks claude push-notification","timeout":10,"async":true}]}],"PermissionRequest":[{"matcher":"","hooks":[{"type":"command","command":"\"${CMUX_CLAUDE_HOOK_CMUX_BIN:-cmux}\" hooks feed --source claude","timeout":125}]}]}}'
HOOKS_JSON='{"preferredNotifChannel":"notifications_disabled","hooks":{"SessionStart":[{"matcher":"","hooks":[{"type":"command","command":"\"${CMUX_CLAUDE_HOOK_CMUX_BIN:-cmux}\" hooks claude session-start","timeout":10}]}],"Stop":[{"matcher":"","hooks":[{"type":"command","command":"\"${CMUX_CLAUDE_HOOK_CMUX_BIN:-cmux}\" hooks claude stop","timeout":10}]},{"matcher":"","hooks":[{"type":"command","command":"\"${CMUX_CLAUDE_HOOK_CMUX_BIN:-cmux}\" hooks feed --source claude","timeout":10,"async":true}]},{"matcher":"","hooks":[{"type":"command","command":"\"${CMUX_CLAUDE_HOOK_CMUX_BIN:-cmux}\" hooks claude auto-name","timeout":120,"async":true}]}],"SubagentStop":[{"matcher":"","hooks":[{"type":"command","command":"\"${CMUX_CLAUDE_HOOK_CMUX_BIN:-cmux}\" hooks feed --source claude","timeout":10,"async":true}]}],"SessionEnd":[{"matcher":"","hooks":[{"type":"command","command":"\"${CMUX_CLAUDE_HOOK_CMUX_BIN:-cmux}\" hooks claude session-end","timeout":10}]}],"Notification":[{"matcher":"","hooks":[{"type":"command","command":"\"${CMUX_CLAUDE_HOOK_CMUX_BIN:-cmux}\" hooks claude notification","timeout":10}]}],"UserPromptSubmit":[{"matcher":"","hooks":[{"type":"command","command":"\"${CMUX_CLAUDE_HOOK_CMUX_BIN:-cmux}\" hooks claude prompt-submit","timeout":10}]}],"PreToolUse":[{"matcher":"CronCreate","hooks":[{"type":"command","command":"\"${CMUX_CLAUDE_HOOK_CMUX_BIN:-cmux}\" hooks claude cron-create-guard","timeout":5}]},{"matcher":"","hooks":[{"type":"command","command":"\"${CMUX_CLAUDE_HOOK_CMUX_BIN:-cmux}\" hooks claude pre-tool-use","timeout":5,"async":true}]}],"PostToolUse":[{"matcher":"PushNotification","hooks":[{"type":"command","command":"\"${CMUX_CLAUDE_HOOK_CMUX_BIN:-cmux}\" hooks claude push-notification","timeout":10,"async":true}]}],"PermissionRequest":[{"matcher":"","hooks":[{"type":"command","command":"\"${CMUX_CLAUDE_HOOK_CMUX_BIN:-cmux}\" hooks feed --source claude","timeout":125}]}]}}'

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P1 Old Timeout Assertion Fails

The existing assertion in tests/test_claude_wrapper_hooks.py:610 requires a SessionEnd timeout of at most two seconds. This change makes the only injected SessionEnd timeout 10 seconds, so the test fails until its expectation is updated.

@greptile-apps

greptile-apps Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR gives the synchronous Claude Code session-end cleanup more time to finish. The main changes are:

  • Raises the SessionEnd hook timeout from 1 second to 10 seconds.
  • Keeps session-end cleanup synchronous during teardown.
  • Documents the cold-start cancellation that motivated the change.

Confidence Score: 5/5

This looks safe to merge.

  • No blocking issues found in the changed code.
  • Successful cleanup returns immediately and does not consume the full deadline.
  • The longer deadline directly prevents cold-start cancellation during teardown.

Important Files Changed

Filename Overview
Resources/bin/cmux-claude-wrapper Raises the injected SessionEnd deadline to match sibling synchronous hooks without changing the command, ordering, or cleanup behavior.

Reviews (2): Last reviewed commit: "Fix SessionEnd hook cancelled on exit by..." | Re-trigger Greptile

@greptile-apps

greptile-apps Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR gives Claude session cleanup more time to finish during exit. The main changes are:

  • Raises the synchronous SessionEnd hook timeout from 1 to 10 seconds.
  • Documents why cold-start and socket connection can exceed one second.

Confidence Score: 5/5

The runtime change looks safe, with one test expectation to update.

  • The new deadline matches other synchronous lifecycle hooks.
  • The hook remains synchronous and its command is unchanged.
  • The existing SessionEnd timeout assertion will fail until updated.

tests/test_claude_wrapper_hooks.py

Important Files Changed

Filename Overview
Resources/bin/cmux-claude-wrapper Raises the SessionEnd timeout to 10 seconds, but the existing wrapper-hook test still enforces a two-second maximum.

Reviews (3): Last reviewed commit: "Fix SessionEnd hook cancelled on exit by..." | Re-trigger Greptile

# on the workspaceAutoNaming setting via a socket probe, so it is a
# no-op when the feature is disabled.
HOOKS_JSON='{"preferredNotifChannel":"notifications_disabled","hooks":{"SessionStart":[{"matcher":"","hooks":[{"type":"command","command":"\"${CMUX_CLAUDE_HOOK_CMUX_BIN:-cmux}\" hooks claude session-start","timeout":10}]}],"Stop":[{"matcher":"","hooks":[{"type":"command","command":"\"${CMUX_CLAUDE_HOOK_CMUX_BIN:-cmux}\" hooks claude stop","timeout":10}]},{"matcher":"","hooks":[{"type":"command","command":"\"${CMUX_CLAUDE_HOOK_CMUX_BIN:-cmux}\" hooks feed --source claude","timeout":10,"async":true}]},{"matcher":"","hooks":[{"type":"command","command":"\"${CMUX_CLAUDE_HOOK_CMUX_BIN:-cmux}\" hooks claude auto-name","timeout":120,"async":true}]}],"SubagentStop":[{"matcher":"","hooks":[{"type":"command","command":"\"${CMUX_CLAUDE_HOOK_CMUX_BIN:-cmux}\" hooks feed --source claude","timeout":10,"async":true}]}],"SessionEnd":[{"matcher":"","hooks":[{"type":"command","command":"\"${CMUX_CLAUDE_HOOK_CMUX_BIN:-cmux}\" hooks claude session-end","timeout":1}]}],"Notification":[{"matcher":"","hooks":[{"type":"command","command":"\"${CMUX_CLAUDE_HOOK_CMUX_BIN:-cmux}\" hooks claude notification","timeout":10}]}],"UserPromptSubmit":[{"matcher":"","hooks":[{"type":"command","command":"\"${CMUX_CLAUDE_HOOK_CMUX_BIN:-cmux}\" hooks claude prompt-submit","timeout":10}]}],"PreToolUse":[{"matcher":"CronCreate","hooks":[{"type":"command","command":"\"${CMUX_CLAUDE_HOOK_CMUX_BIN:-cmux}\" hooks claude cron-create-guard","timeout":5}]},{"matcher":"","hooks":[{"type":"command","command":"\"${CMUX_CLAUDE_HOOK_CMUX_BIN:-cmux}\" hooks claude pre-tool-use","timeout":5,"async":true}]}],"PostToolUse":[{"matcher":"PushNotification","hooks":[{"type":"command","command":"\"${CMUX_CLAUDE_HOOK_CMUX_BIN:-cmux}\" hooks claude push-notification","timeout":10,"async":true}]}],"PermissionRequest":[{"matcher":"","hooks":[{"type":"command","command":"\"${CMUX_CLAUDE_HOOK_CMUX_BIN:-cmux}\" hooks feed --source claude","timeout":125}]}]}}'
HOOKS_JSON='{"preferredNotifChannel":"notifications_disabled","hooks":{"SessionStart":[{"matcher":"","hooks":[{"type":"command","command":"\"${CMUX_CLAUDE_HOOK_CMUX_BIN:-cmux}\" hooks claude session-start","timeout":10}]}],"Stop":[{"matcher":"","hooks":[{"type":"command","command":"\"${CMUX_CLAUDE_HOOK_CMUX_BIN:-cmux}\" hooks claude stop","timeout":10}]},{"matcher":"","hooks":[{"type":"command","command":"\"${CMUX_CLAUDE_HOOK_CMUX_BIN:-cmux}\" hooks feed --source claude","timeout":10,"async":true}]},{"matcher":"","hooks":[{"type":"command","command":"\"${CMUX_CLAUDE_HOOK_CMUX_BIN:-cmux}\" hooks claude auto-name","timeout":120,"async":true}]}],"SubagentStop":[{"matcher":"","hooks":[{"type":"command","command":"\"${CMUX_CLAUDE_HOOK_CMUX_BIN:-cmux}\" hooks feed --source claude","timeout":10,"async":true}]}],"SessionEnd":[{"matcher":"","hooks":[{"type":"command","command":"\"${CMUX_CLAUDE_HOOK_CMUX_BIN:-cmux}\" hooks claude session-end","timeout":10}]}],"Notification":[{"matcher":"","hooks":[{"type":"command","command":"\"${CMUX_CLAUDE_HOOK_CMUX_BIN:-cmux}\" hooks claude notification","timeout":10}]}],"UserPromptSubmit":[{"matcher":"","hooks":[{"type":"command","command":"\"${CMUX_CLAUDE_HOOK_CMUX_BIN:-cmux}\" hooks claude prompt-submit","timeout":10}]}],"PreToolUse":[{"matcher":"CronCreate","hooks":[{"type":"command","command":"\"${CMUX_CLAUDE_HOOK_CMUX_BIN:-cmux}\" hooks claude cron-create-guard","timeout":5}]},{"matcher":"","hooks":[{"type":"command","command":"\"${CMUX_CLAUDE_HOOK_CMUX_BIN:-cmux}\" hooks claude pre-tool-use","timeout":5,"async":true}]}],"PostToolUse":[{"matcher":"PushNotification","hooks":[{"type":"command","command":"\"${CMUX_CLAUDE_HOOK_CMUX_BIN:-cmux}\" hooks claude push-notification","timeout":10,"async":true}]}],"PermissionRequest":[{"matcher":"","hooks":[{"type":"command","command":"\"${CMUX_CLAUDE_HOOK_CMUX_BIN:-cmux}\" hooks feed --source claude","timeout":125}]}]}}'

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 SessionEnd Test Contract Breaks

The existing test in tests/test_claude_wrapper_hooks.py:607-613 requires the SessionEnd timeout to be at most two seconds. Changing the only matching hook to 10 seconds makes that assertion fail, so the test expectation must be updated with this behavior change.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

@teamleaderleo

Copy link
Copy Markdown
Collaborator

Thanks for this! SessionEnd now runs as a queued hook with a longer timeout landed on main in #8537. You opened this first, so you got there first. Closing since main covers it now.

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.

SessionEnd hook has timeout:1 → "Hook cancelled" on normal session exit

2 participants