Skip to content

fix(hat): don't rename to a stem-less dotfile on a degenerate model answer#32

Merged
marksverdhei merged 1 commit into
mainfrom
fix/sanitize-empty-name-dotfile
Jun 27, 2026
Merged

fix(hat): don't rename to a stem-less dotfile on a degenerate model answer#32
marksverdhei merged 1 commit into
mainfrom
fix/sanitize-empty-name-dotfile

Conversation

@marksverdhei

Copy link
Copy Markdown
Owner

Bug

sanitize_name appends the original extension unconditionally:

if preserve_ext == "true" and orig_ext:
    if "." in name:
        name = name.rsplit(".", 1)[0]
    name = name + "." + orig_ext

So when the model returns nothing usable — an empty answer, a think-only answer (a reasoning model that spent its budget inside <think> and emitted no name), or punctuation like . / / — the result is a stem-less name like .jpg:

sanitize_name ""                              "true" "jpg"  ->  .jpg
sanitize_name "<think>…ran out of tokens</think>" "true" "jpg"  ->  .jpg
sanitize_name "."                             "true" "jpg"  ->  .jpg

That's non-empty, so it slips past the caller's [[ -z "$suggested" ]] guard (hat:991) and renames the user's file to a hidden, stem-less file — effectively losing it.

Fix

Strip leftover dots/dashes from the stem; if nothing remains, emit no name so the empty-guard rejects the rename and reports (no suggestion):

    name = name.strip("-.")
    name = name + "." + orig_ext if name else ""

Tests

3 regression tests (empty / think-only / punctuation-only → ""). They fail on the old code (actual: .jpg) and pass with the fix. All existing sanitize cases unchanged. 80/80 bats pass.

🤖 Generated with Claude Code

…nswer

`sanitize_name` appended the original extension unconditionally, so an empty
or unusable answer (e.g. a reasoning model that spent its whole budget inside
<think> and emitted no name, or punctuation like "." / "/") produced a
stem-less name like ".jpg". That's non-empty, so it slips past the caller's
`-z "$suggested"` guard and renames the file to a hidden, stem-less file —
effectively losing it.

Strip leftover dots/dashes from the stem and, if nothing remains, emit no name
so the empty-guard rejects the rename and reports "(no suggestion)".

Adds 3 regression tests (empty / think-only / punctuation-only → no name).
All 80 bats tests pass.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@marksverdhei marksverdhei merged commit 0f2e25e into main Jun 27, 2026
1 check passed
@marksverdhei marksverdhei deleted the fix/sanitize-empty-name-dotfile branch June 27, 2026 17:33
marksverdhei added a commit that referenced this pull request Jun 27, 2026
Adds (newest first, matching existing style):
- #32 stem-less dotfile guard
- #30 video file support
- #28 --preview / -p flag
- #27 is_audio ftyp false-positive fix
- #20 audio file support

Skipped pure-docs (#15, #16, #17, #31), CI infra (#29), and test-only
rebases (#25) — same selection rule the prior entries used.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant