Skip to content

write_file creates a missing parent directory inside the root - #186

Merged
adityak74 merged 1 commit into
mainfrom
fix/write-file-creates-parent
Sep 6, 2026
Merged

write_file creates a missing parent directory inside the root#186
adityak74 merged 1 commit into
mainfrom
fix/write-file-creates-parent

Conversation

@adityak74

Copy link
Copy Markdown
Contributor

write_file refused to write into a directory that did not exist yet: resolve_for_create canonicalized the parent first, and a missing parent fails that call. A model that never shells out mkdir -p then repeats the same failing write until the repeat guard ends the attempt. In the terminal-bench-science oracle run of 2026-09-05, dots-3-note-preview did exactly that: 12 write_file calls, 12 errors, 0 files created, across six tasks whose images ship /app/data and not /app/results. The three models that scored before it all ran mkdir -p from the shell first, which is why the harness had not been caught.

The tool now creates a missing parent the way an editor does, without loosening the root check:

  • .. anywhere in the path is refused before anything is made, so nothing can be created above the nearest existing ancestor.
  • That ancestor is canonicalized and checked against the root before create_dir_all runs, so a symlink out of the root creates nothing on the far side.
  • The final canonical check on the parent stays as it was.

Tests cover the new parent, an escaping path that must create nothing, and a symlink out of the root that must create nothing. The tool description tells the model that parent directories are created.

https://claude.ai/code/session_01ADjombyM8oH114zG9FnMxo

resolve_for_create canonicalized the parent first, so a directory that
did not exist yet failed the write. A model that never runs mkdir -p
then repeats the same failing write until the repeat guard ends the
attempt; dots-3 lost every write of an oracle run that way. The parent
is now created the way an editor would, with .. refused up front and
the nearest existing ancestor checked against the root before anything
is made, so a symlink out of the root creates nothing on the far side.

Claude-Session: https://claude.ai/code/session_01ADjombyM8oH114zG9FnMxo
@adityak74
adityak74 merged commit 215d321 into main Sep 6, 2026
7 checks passed
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