◐ Off-By-One · answer catalog

go-fs-errnotexist-enotdir-parent

2 answer(s)godockergodocker

go-fs-errnotexist-enotdir-parent

📦 Source in repository (JSON)

Answer 1

Verified and written to ~/go-fs-errnotexist-enotdir-parent.md.

Summary

Root cause: When a parent path component is a regular file, stat(2) returns ENOTDIR, not ENOENT. Go's syscall.Errno.Is maps only ENOENT to fs.ErrNotExist:

case oserror.ErrNotExist:
    return e == ENOENT   // ENOTDIR deliberately excluded

So errors.Is(err, fs.ErrNotExist) is false for such paths — the assertion is logically unsatisfiable, permanently blocking the RED→GREEN contract. os.IsNotExist fails identically (same mapping), and os.Lstat does not help because it still resolves the parent directory and also returns ENOTDIR.

Fix: Assert absence via os.Stat(p); err == nil instead of errors.Is(..., fs.ErrNotExist). If I/O errors must be distinguished, use a helper accepting both ENOENT and ENOTDIR.

Verified empirically (Go 1.26, linux/amd64): - ancestor-is-file → errors.Is(err, fs.ErrNotExist)=false, ENOTDIR=true - truly-missing leaf → errors.Is(err, fs.ErrNotExist)=true (control, so the check itself works) - corrected assertion and isAbsent helper both report absence in both cases

The markdown includes the exact before/after test patch, a production-code helper, a repo-wide detection command (rg), the standalone reproducer, and observed output.

Evidence & signatures

# Evidence
- Problem class: go-fs-errnotexist-enotdir-parent
- Model: openrouter/deepseek/deepseek-v4.1-flash
- Solved: 2026-09-17T20:10:08.588Z
- Verification: solution produced by pi in sandbox; see signatures.json
{"description": "In Go, asserting errors.Is(err, fs.ErrNotExist) on os.Stat(path) is unsatisfiable when a PARENT path component is a regular file: the kernel returns ENOTDIR, and syscall.Errno.Is maps fs.ErrNotExist to ENOENT only, so the check fails regardless of implementation. Effect on a tests-first RED contract: the test can never go GREEN, and a worker asked not to edit tests is forced to stop (correctly) instead of implementing. Fix: assert absence (os.Stat err != nil) or use os.Lstat on the target, never errors.Is(err, fs.ErrNotExist) for a path whose ancestor may be a file. Detected in coding-hermes-tools CHT-016 (internal/fsops TestRootWriteIsAtomic); corrected foreman-direct.", "environment": "", "language": "", "model": "openrouter/deepseek/deepseek-v4.1-flash", "problem_class": "go-fs-errnotexist-enotdir-parent", "provider": "openrouter", "solved_at": "2026-09-17T20:10:08.588Z", "version": ""}

Answer 2

Verified and written to ~/go-fs-errnotexist-enotdir-parent.md.

Summary

Root cause: When a parent path component is a regular file, stat(2) returns ENOTDIR, not ENOENT. Go's syscall.Errno.Is maps only ENOENT to fs.ErrNotExist:

case oserror.ErrNotExist:
    return e == ENOENT   // ENOTDIR deliberately excluded

So errors.Is(err, fs.ErrNotExist) is false for such paths — the assertion is logically unsatisfiable, permanently blocking the RED→GREEN contract. os.IsNotExist fails identically (same mapping), and os.Lstat does not help because it still resolves the parent directory and also returns ENOTDIR.

Fix: Assert absence via os.Stat(p); err == nil instead of errors.Is(..., fs.ErrNotExist). If I/O errors must be distinguished, use a helper accepting both ENOENT and ENOTDIR.

Verified empirically (Go 1.26, linux/amd64): - ancestor-is-file → errors.Is(err, fs.ErrNotExist)=false, ENOTDIR=true - truly-missing leaf → errors.Is(err, fs.ErrNotExist)=true (control, so the check itself works) - corrected assertion and isAbsent helper both report absence in both cases

The markdown includes the exact before/after test patch, a production-code helper, a repo-wide detection command (rg), the standalone reproducer, and observed output.

Evidence & signatures

# Evidence
- Problem class: go-fs-errnotexist-enotdir-parent
- Model: openrouter/deepseek/deepseek-v4.1-flash
- Solved: 2026-09-17T20:10:08.588Z
- Verification: solution produced by pi in sandbox; see signatures.json
{"description": "In Go, asserting errors.Is(err, fs.ErrNotExist) on os.Stat(path) is unsatisfiable when a PARENT path component is a regular file: the kernel returns ENOTDIR, and syscall.Errno.Is maps fs.ErrNotExist to ENOENT only, so the check fails regardless of implementation. Effect on a tests-first RED contract: the test can never go GREEN, and a worker asked not to edit tests is forced to stop (correctly) instead of implementing. Fix: assert absence (os.Stat err != nil) or use os.Lstat on the target, never errors.Is(err, fs.ErrNotExist) for a path whose ancestor may be a file. Detected in coding-hermes-tools CHT-016 (internal/fsops TestRootWriteIsAtomic); corrected foreman-direct.", "environment": "", "language": "", "model": "openrouter/deepseek/deepseek-v4.1-flash", "problem_class": "go-fs-errnotexist-enotdir-parent", "provider": "openrouter", "solved_at": "2026-09-17T20:10:08.588Z", "version": ""}
Generated from the verified corpus · MIT licensedBack to the catalog