Skill-scoped hooks (PreToolUse/Stop) still persist after skill completes — re-report of #30874, reproducible on 2026-07-31
Summary
This is a re-report of #30874, which was auto-closed by the stale bot without a fix. I independently reproduced the exact same bug on 2026-07-31 and want to flag that it's still affecting people, including at least one other user (yuke-x68) who reported in that issue's comments that the problem also affects PostToolUse and Stop, not just PreToolUse.
Description
Hooks defined in a skill's YAML frontmatter (hooks: field) are documented as being "scoped to the component's lifecycle and only run when that component is active... cleaned up when it finishes" (hooks doc). In practice, once a skill with a hooks block is invoked, its hooks remain registered and continue firing for the rest of the session, even in turns where the skill is never invoked again.
Reproduction (2026-07-31)
- Create a throwaway skill with a
PreToolUsehook that logs a timestamp on everyBashcall:
---
name: hook-scope-test
description: test skill
user-invocable: false
hooks:
PreToolUse:
- matcher: "Bash"
hooks:
- type: command
command: "date '+%Y-%m-%d %H:%M:%S PreToolUse fired' >> /path/to/log.txt"
---
- Invoke the skill once via the Skill tool. Confirm the hook fires on subsequent
Bashcalls within the same turn (it does — this part matches the docs). - Send a completely unrelated follow-up user message, starting a new turn, without re-invoking the skill.
- Run any
Bashcommand in that new turn.
Expected behavior
Per the docs, the hook should have been cleaned up when the skill's turn finished, so step 4's Bash call should not trigger it.
Actual behavior
The hook still fires in step 4. The log file keeps accumulating new timestamped lines for every subsequent Bash call for the rest of the session, regardless of whether the skill is invoked again.
Why this matters
This makes skill-scoped hooks unusable for their apparently intended purpose: gating tool access only while a specific skill is doing its work (e.g., a read-only audit skill that wants to disallowed-tools/hook-block writes only during its own execution). Right now, invoking such a skill once has session-wide side effects indistinguishable from putting the same hook in settings.json directly — except it's implicit and easy to forget about, since nothing in the UI indicates "this hook is still active from a skill you ran 20 turns ago."
Related
- #30874 (original report, same bug, auto-closed as stale without a fix — filing this because it's still reproducible today and per the bot's own suggestion: "Please open a new issue if this is still relevant")
This issue has 4 comments on GitHub. Read the full discussion on GitHub ↗