Summary
hooks/precompact-transcript-backup.sh uses mapfile, which is a bash 4+ builtin. macOS ships bash 3.2 by default (/bin/bash and /usr/bin/env bash both resolve to 3.2.57 unless the user has installed a newer bash via Homebrew). On a stock Mac, the rotation step fails every time:
precompact-transcript-backup.sh: line 23: mapfile: command not found
Why this is easy to miss
The script wraps everything in trap 'exit 0' ERR (correctly, for fail-open behavior), so the failure is completely silent — no error surfaces anywhere in Claude Code. The visible symptom is that ~/.claude/backups/transcripts/ grows without bound, one file per compaction, forever, for any user who hasn't separately installed a newer bash.
line 23: mapfile -t OLD_BACKUPS < <(find "$BACKUP_DIR" -maxdepth 1 -type f -name "*-${SESSION_ID}.jsonl" -print 2>/dev/null | sort -r | tail -n +21)
line 24: if [[ ${#OLD_BACKUPS[@]} -gt 0 ]]; then
line 25: rm -f "${OLD_BACKUPS[@]}" 2>/dev/null || true
line 26: fi
Suggested fix
Replace the mapfile + array with a portable while read loop (no bash4+ dependency):
find "$BACKUP_DIR" -maxdepth 1 -type f -name "*-${SESSION_ID}.jsonl" -print 2>/dev/null | sort -r | tail -n +21 | while IFS= read -r old; do
rm -f "$old" 2>/dev/null || true
done
I verified this fix locally: seeded 25 fake backup files for a session, ran the patched script, and confirmed it correctly pruned down to 20 (the intended retention count) with bash --version = 3.2.57(1)-release.
Environment
- macOS (Darwin 25.5.0, arm64), no Homebrew bash installed
bash --version → GNU bash, version 3.2.57(1)-release (arm64-apple-darwin25)
- compact-plus commit:
098e8f7 (main, at time of testing)
Happy to open a PR with the fix above if useful.
Summary
hooks/precompact-transcript-backup.shusesmapfile, which is a bash 4+ builtin. macOS ships bash 3.2 by default (/bin/bashand/usr/bin/env bashboth resolve to 3.2.57 unless the user has installed a newer bash via Homebrew). On a stock Mac, the rotation step fails every time:Why this is easy to miss
The script wraps everything in
trap 'exit 0' ERR(correctly, for fail-open behavior), so the failure is completely silent — no error surfaces anywhere in Claude Code. The visible symptom is that~/.claude/backups/transcripts/grows without bound, one file per compaction, forever, for any user who hasn't separately installed a newer bash.Suggested fix
Replace the
mapfile+ array with a portablewhile readloop (no bash4+ dependency):I verified this fix locally: seeded 25 fake backup files for a session, ran the patched script, and confirmed it correctly pruned down to 20 (the intended retention count) with
bash --version= 3.2.57(1)-release.Environment
bash --version→GNU bash, version 3.2.57(1)-release (arm64-apple-darwin25)098e8f7(main, at time of testing)Happy to open a PR with the fix above if useful.