Skip to content

Standalone .github/hooks/*.json postToolUse hook never fires (repo-root, non-plugin) #4520

Description

@xaviervv

Describe the bug

A postToolUse hook defined in a standalone, repo-root .github/hooks/*.json file (not shipped as part of a plugin) never fires. This isn't a config error being silently dropped in the way #3872 describes -- the debug log shows no trace of the hook file being discovered or read at all, not even a rejection.

This is adjacent to several existing reports but distinct from each:

Affected version

@github/copilot (npm) 1.0.80, Windows 11 (see note below on an inconclusive Linux attempt).

Steps to reproduce the behavior

  1. In a git repo, create .github/hooks/validate-dockerfile.json:
    {
      "version": 1,
      "hooks": {
        "postToolUse": [
          { "type": "command", "bash": "path/to/shared-script.sh", "powershell": "path/to/shared-script.ps1", "cwd": ".", "timeoutSec": 30 }
        ]
      }
    }
    (shape taken directly from the documented schema at https://docs.github.com/en/copilot/how-tos/copilot-cli/customize-copilot/use-hooks)
  2. The referenced script is instrumented to append its real invocation (stdin, argv, cwd, env) to a log file, so firing can be verified directly rather than inferred.
  3. Start a non-interactive session (copilot -p --allow-all-tools "edit the Dockerfile to add one line") that edits a file matching a tool call the hook should intercept.
  4. The edit succeeds. The log file is never created -- the hook script is never invoked.

Repeated across 4 independent variations on Windows, all with the same result (hook never fires):

  • Baseline config as above, no matcher field.
  • Same, with --experimental passed at launch.
  • Same, with an explicit "matcher": "*" field added (in case an absent matcher means "match nothing" rather than "match everything").
  • Same, but the triggering edit made via the Write tool (creating the file) instead of Edit (modifying an existing file), to rule out a tool-specific gap.

~/.copilot/logs/process-*.log for the Windows runs shows a NativeHookPipelineProcessor registered for postToolExecution in general, but contains zero references to validate-dockerfile.json, .github/hooks, or any hook-discovery trace for the test repo -- consistent with the hook file never being read, not merely filtered out after being read (which is what #3872's fix would surface as a debug-level "ignoring unknown event" line; no such line appears here either).

A Linux (WSL2 Ubuntu, same 1.0.80) attempt was made but is inconclusive, not confirmatory -- npx @github/copilot was genuinely invoked, but no ~/.copilot/logs/process-*.log was produced at all, so it can't be distinguished from the session simply not reaching the test step. Not claiming cross-platform confirmation until this is re-verified with the same log-level rigor as the Windows finding above.

Expected behavior

A postToolUse hook in a standalone repo-root .github/hooks/*.json file, using the documented schema, should fire on a matching tool call -- the same way it does for Claude Code's equivalent PostToolUse hook in .claude/settings.json, which was verified firing correctly in the same test session as a control.

Additional context

  • Found while verifying whether a single validator script could be shared across a Claude Code PostToolUse hook and a Copilot CLI postToolUse hook, for a cross-tool developer tooling project.
  • Windows-specificity not yet ruled out -- see the inconclusive Linux note above.
  • This report was drafted with AI assistance (Claude Code) based on a live, instrumented reproduction; happy to provide the raw log files or test fixtures if useful for triage.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:configurationConfig files, instruction files, settings, and environment variables

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions