claude-code - 💡(How to fix) Fix Bash rename loop silently overwrote 21 user files via failed BASH_REMATCH expansion [1 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
anthropics/claude-code#53151Fetched 2026-04-26 05:23:06
View on GitHub
Comments
1
Participants
2
Timeline
6
Reactions
0
Timeline (top)
labeled ×5commented ×1

Claude Code (Opus 4.7, 1M context) wrote and executed a multi-file mv rename loop using [[ "$f" =~ regex ]] with ${BASH_REMATCH[1]} etc. for capture extraction. The captures did not expand at runtime — every iteration produced the same target filename, and the loop silently overwrote 21 of 22 files in the destination directory. Only the last file in alphabetical sort order survived.

Error Message

  1. The user had paid for newspapers.com access, hit the daily rate limit during the original click-through, and could not redownload to recover — turning a tool error into 24 hours of dead time and an hour of wasted click-through work.

Root Cause

The user had downloaded 22 unique JPGs to ~/Downloads/ named Pueblo_Chieftain_YYYY_MM_DD_PP.jpg. I (Claude) wrote a rename script intended to convert them to chuck_YYYY_mmmDD_pueblo_chieftain_pPP.jpg. The script used a regex match in a for loop with BASH_REMATCH for capture extraction. At runtime the captures evaluated to empty strings (likely because the script ran under sh rather than bash, where [[ =~ ]] is unsupported and BASH_REMATCH is unset), so the new filename collapsed to chuck___pueblo_chieftain_p.jpg for every file. mv overwrote silently. Only the alphabetically-last source file (a 1985 dated file beating all the 1951–1976 sources) was preserved.

Fix Action

Fix / Workaround

Suggested mitigations

RAW_BUFFERClick to expand / collapse

Summary

Claude Code (Opus 4.7, 1M context) wrote and executed a multi-file mv rename loop using [[ "$f" =~ regex ]] with ${BASH_REMATCH[1]} etc. for capture extraction. The captures did not expand at runtime — every iteration produced the same target filename, and the loop silently overwrote 21 of 22 files in the destination directory. Only the last file in alphabetical sort order survived.

Reproduction

The user had downloaded 22 unique JPGs to ~/Downloads/ named Pueblo_Chieftain_YYYY_MM_DD_PP.jpg. I (Claude) wrote a rename script intended to convert them to chuck_YYYY_mmmDD_pueblo_chieftain_pPP.jpg. The script used a regex match in a for loop with BASH_REMATCH for capture extraction. At runtime the captures evaluated to empty strings (likely because the script ran under sh rather than bash, where [[ =~ ]] is unsupported and BASH_REMATCH is unset), so the new filename collapsed to chuck___pueblo_chieftain_p.jpg for every file. mv overwrote silently. Only the alphabetically-last source file (a 1985 dated file beating all the 1951–1976 sources) was preserved.

Recovery was not possible: APFS local snapshots predated the downloads (snapshot 20:50 PM, downloads 20:59–21:05 PM, destruction 21:27 PM — files only existed in the window between snapshots).

Why this is bad

  1. The agent did not dry-run the rename before executing despite touching 22 files.
  2. There is no built-in warning when a multi-file mv produces colliding target paths.
  3. The user had paid for newspapers.com access, hit the daily rate limit during the original click-through, and could not redownload to recover — turning a tool error into 24 hours of dead time and an hour of wasted click-through work.

Suggested mitigations

  1. When the agent generates bulk file operations (rename loops, mv patterns, find -exec), it should:
    • Run a dry-run first that prints the proposed before/after pairs
    • Detect target-name collisions before invoking the actual mv
  2. Prefer Python os.rename or rename(1) with explicit collision-checking over hand-rolled bash regex with BASH_REMATCH.
  3. Pattern-recognize "I'm renaming N>1 files to a derived pattern" as high-blast-radius and confirm before executing autonomously.
  4. Consider a small wrapper or Bash safety guidance reminder: if a script uses BASH_REMATCH, ensure invocation is bash, not sh, and add a sanity check on the captured groups before using them.

User impact

User lost 21 high-resolution newspaper page images, ~1 hour of supervised click-through, and 24 hours of forward research time during a personal genealogy project. Files are recoverable only by re-doing the click-through after the rate limit clears. The mistake was framed by the agent as bash carelessness, which the user accepted, but the underlying defect is that a destructive multi-file operation ran with no preview and no collision detection.

extent analysis

TL;DR

Run a dry-run before executing bulk file operations and implement collision detection to prevent silent overwrites.

Guidance

  • Use a dry-run to print proposed before/after pairs for bulk file operations to catch potential issues before execution.
  • Implement collision detection to warn about target-name collisions before invoking the actual mv command.
  • Consider using Python os.rename or rename(1) with explicit collision-checking instead of hand-rolled bash regex with BASH_REMATCH.
  • Add a sanity check to ensure the script is invoked with bash and not sh when using BASH_REMATCH.

Example

# Dry-run example
for f in ~/Downloads/Pueblo_Chieftain_*.jpg; do
  new_name="chuck_${f:20:4}_${f:25:3}${f:28:2}_pueblo_chieftain_p${f:18:2}.jpg"
  echo "mv $f $new_name"
done

Notes

The issue highlights the importance of careful handling of bulk file operations, especially when using regex and BASH_REMATCH. The suggested mitigations can help prevent similar incidents in the future.

Recommendation

Apply the suggested mitigations, particularly running a dry-run and implementing collision detection, to prevent silent overwrites and ensure safe execution of bulk file operations.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING