Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

Planning hooks crash on git-bash/Windows & Linux — stat -f is BSD-only

Open
#2 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
3/5
Estimated time
1-2 days
Newbie friendliness
78/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Quiet
Tech stack
shell

Research direction

Start with .claude/hooks/user-prompt-submit.sh, .claude/hooks/session-start.sh, and .claude/hooks/stop.sh, then reproduce with the command in the issue on a GNU system. Update the mtime handling and inspect tests/hooks/test-stop.sh for the deterministic timestamp case. Done means ./scripts/quality.sh passes all 56 tests on git-bash/Linux while macOS behavior remains working.

Written by the indexing model from the issue text.

Description

Environment

  • OS: Windows 11 (git-bash) — also affects any GNU coreutils system (Linux). Works fine on macOS, which is why it likely went unnoticed.
  • Affected files: .claude/hooks/user-prompt-submit.sh, .claude/hooks/session-start.sh, .claude/hooks/stop.sh

Summary

The planning hooks silently crash on git-bash / Linux. As a side effect, scripts/quality.sh fails (~17 hook test cases) and the UserPromptSubmit / Stop / SessionStart hooks never run — so the "surface the active plan" feature is effectively dead on Windows/Linux.

Note: the test suite reports 56/56 on macOS but the hooks never execute on GNU systems (Linux/git-bash) — which is why this likely went unnoticed.

Root cause

Each hook reads the file mtime with:

mtime=$(stat -f %m "$progress" 2>/dev/null || stat -c %Y "$progress" 2>/dev/null || echo 0)

stat -f %m is the BSD/macOS syntax (works on macOS). On GNU stat, -f means "display filesystem status" — it does not fail, it prints a non-numeric string. Since it's tried first, the || fallback to stat -c %Y never fires, $mtime gets text, and the next line if (( mtime > newest )) evaluates that text as a variable name. Under set -euo pipefail this throws:

.claude/hooks/user-prompt-submit.sh: line 28: File: unbound variable

and the hook exits 1.

Steps to reproduce (git-bash)

echo '{}' | bash .claude/hooks/user-prompt-submit.sh; echo $?   # prints 1, should be 0
./scripts/quality.sh                                            # fails on hook tests

Fix (cross-platform, no macOS regression)

Try GNU first, fall back to BSD, and guard that the result is numeric:

mtime=$(stat -c %Y "$progress" 2>/dev/null || stat -f %m "$progress" 2>/dev/null || echo 0)
[[ "$mtime" =~ ^[0-9]+$ ]] || mtime=0

Apply to all three hooks. On macOS, stat -c fails → falls back to stat -f %m (behavior unchanged); on GNU, stat -c %Y returns the epoch.

Bonus (minor, test robustness)

In tests/hooks/test-stop.sh, the "multi-feature" case uses a plain touch, which can tie on coarse-granularity filesystems (Windows) and make the strict > comparison pick the wrong file. Forcing an explicit time makes it deterministic:

touch -d '2037-01-01 00:00' .claude/plans/features/002-newer/progress.md

Result

After both changes, ./scripts/quality.sh passes 56/56 on git-bash.

Dominant language
Shell
Stars
18
Forks
1
PR merge metrics
No merged PRs in 30d

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Similar issues

More Shell/Bash issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.