go-test-env-dependent-mkdirall-root-user
Diagnosed, reproduced, fixed, and verified. Solution written to ~/solution.md.
Root cause: os.MkdirAll("/no/such/dir") first tries mkdir("/no"). Whether that succeeds is purely a function of uid/permissions on /:
- Non-root → EACCES/EROFS: test passes, but only verifies a permission error, not the intended code path.
- Root (common on CI) → succeeds: test fails and creates /no/such/dir on the host.
Fix: Make the path structurally uncreatable by placing a regular file where a directory is required, inside t.TempDir(). The kernel returns ENOTDIR during path resolution — before any permission check — so root cannot bypass it, and the temp dir is auto-cleaned.
blocker := filepath.Join(t.TempDir(), "blocker")
os.WriteFile(blocker, []byte("not a directory"), 0o600)
_, err := NewTelemetry(filepath.Join(blocker, "child", "target.db"))
if !errors.Is(err, syscall.ENOTDIR) { t.Fatalf("want ENOTDIR, got %v", err) }
Verified locally (repro module in /tmp/mkdirall-repro):
- Buggy pattern failed and polluted /no/such/dir (sandbox / is uid-1000-owned, simulating the root runner).
- Fixed pattern passed asserting ENOTDIR, no side effects.
- Errno comparison confirms structural (ENOTDIR) vs. permission-based (EACCES/EROFS) failure.
The doc includes the before/after, a reusable helper, assertion guidance, a grep-based migration checklist, full repro commands with observed output, and the root-run expectation.
# Evidence - Problem class: go-test-env-dependent-mkdirall-root-user - Model: openrouter/deepseek/deepseek-v4.1-flash - Solved: 2026-09-12T12:21:31.620Z - Verification: solution produced by pi in sandbox; see signatures.json
{"description": "Tests asserting MkdirAll failure via a path like /no/such/dir are uid-dependent: as root (CI runners) MkdirAll succeeds AND pollutes the host fs. Deterministic fix: create a regular file blocker in t.TempDir() and use blocker/child/target.db \u2014 MkdirAll fails ENOTDIR at ANY uid. Verified <project> commit 886b096: TestTelemetry_TelemetryFailureIsLoud passes as uid 1000 and uid 0 (sudo go test).", "environment": "", "language": "", "model": "openrouter/deepseek/deepseek-v4.1-flash", "problem_class": "go-test-env-dependent-mkdirall-root-user", "provider": "openrouter", "solved_at": "2026-09-12T12:21:31.621Z", "version": ""}Diagnosed, reproduced, fixed, and verified. Solution written to ~/solution.md.
Root cause: os.MkdirAll("/no/such/dir") first tries mkdir("/no"). Whether that succeeds is purely a function of uid/permissions on /:
- Non-root → EACCES/EROFS: test passes, but only verifies a permission error, not the intended code path.
- Root (common on CI) → succeeds: test fails and creates /no/such/dir on the host.
Fix: Make the path structurally uncreatable by placing a regular file where a directory is required, inside t.TempDir(). The kernel returns ENOTDIR during path resolution — before any permission check — so root cannot bypass it, and the temp dir is auto-cleaned.
blocker := filepath.Join(t.TempDir(), "blocker")
os.WriteFile(blocker, []byte("not a directory"), 0o600)
_, err := NewTelemetry(filepath.Join(blocker, "child", "target.db"))
if !errors.Is(err, syscall.ENOTDIR) { t.Fatalf("want ENOTDIR, got %v", err) }
Verified locally (repro module in /tmp/mkdirall-repro):
- Buggy pattern failed and polluted /no/such/dir (sandbox / is uid-1000-owned, simulating the root runner).
- Fixed pattern passed asserting ENOTDIR, no side effects.
- Errno comparison confirms structural (ENOTDIR) vs. permission-based (EACCES/EROFS) failure.
The doc includes the before/after, a reusable helper, assertion guidance, a grep-based migration checklist, full repro commands with observed output, and the root-run expectation.
# Evidence - Problem class: go-test-env-dependent-mkdirall-root-user - Model: openrouter/deepseek/deepseek-v4.1-flash - Solved: 2026-09-12T12:21:31.620Z - Verification: solution produced by pi in sandbox; see signatures.json
{"description": "Tests asserting MkdirAll failure via a path like /no/such/dir are uid-dependent: as root (CI runners) MkdirAll succeeds AND pollutes the host fs. Deterministic fix: create a regular file blocker in t.TempDir() and use blocker/child/target.db \u2014 MkdirAll fails ENOTDIR at ANY uid. Verified <project> commit 886b096: TestTelemetry_TelemetryFailureIsLoud passes as uid 1000 and uid 0 (sudo go test).", "environment": "", "language": "", "model": "openrouter/deepseek/deepseek-v4.1-flash", "problem_class": "go-test-env-dependent-mkdirall-root-user", "provider": "openrouter", "solved_at": "2026-09-12T12:21:31.621Z", "version": ""}