Skip to content

Go go.work audit: false NotAMember for a use path through a missing dir on macOS (breaks macOS test job) #1409

Closed

Description

[agent] Found while checking the full-scope CI run for #1407. It breaks the macOS test job, so tonight's nightly on main is expected to go red.

What fails

vendor::go_consumer_sync::tests::go_work_that_does_not_use_the_project_makes_the_replace_inert (added in #1393, merged 2026-10-11 19:48 UTC, after the last nightly) fails on macos-latest: run 38191238691, job 114624594929.

panicked at crates/socket-patch-core/src/vendor/go_consumer_sync.rs:923:13:
assertion `left == right` failed: ./x/../app
  left: [Workspace { module: "example.com/upstream", version: "v1.0.0", conflict: NotAMember { work_file: "/private/var/folders/.../go.work" } }]
 right: []

The spellings ./app, app, ./app/ and "./app" all pass. Only ./x/../app fails.

Root cause

same_dir_key (go_consumer_sync.rs:468) calls std::fs::canonicalize on the raw joined path <ws>/x/../app. canonicalize needs every component to exist, and x doesn't, so the call errors and the code falls back to the lexical path /var/.../app. The project root does exist and canonicalizes to /private/var/.../app, because /var is a symlink on macOS. The two keys differ, so the use entry doesn't match the project and the audit reports NotAMember.

It isn't only a test problem. Any user whose go.work use path passes through a directory that doesn't exist, and whose project sits under a symlinked path (macOS /var or /tmp, a symlinked home or checkout), gets a false "go.work does not use this project" conflict. Go itself resolves use paths lexically (filepath.Clean), so ./x/../app is a valid member for go.

Repro on Linux

Point TMPDIR at a symlinked directory:

mkdir -p /tmp/real && ln -sfn /tmp/real /tmp/link
TMPDIR=/tmp/link cargo test -p socket-patch-core --lib go_consumer_sync
# 8 passed; 1 failed (same assertion)

Proposed fix (verified locally)

Normalize lexically first, then canonicalize. This matches go's filepath.Clean and still resolves symlinks when the cleaned path exists:

 fn same_dir_key(dir: &Path) -> PathBuf {
     let abs = std::env::current_dir().unwrap_or_default().join(dir);
-    std::fs::canonicalize(&abs)
-        .unwrap_or_else(|_| crate::utils::relpath::normalize_lexically_keeping_escapes(&abs))
+    let lexical = crate::utils::relpath::normalize_lexically_keeping_escapes(&abs);
+    std::fs::canonicalize(&lexical).unwrap_or(lexical)
 }

With this patch, TMPDIR=/tmp/link cargo test -p socket-patch-core --lib go_consumer_sync gives 9 passed. The rest of vendor:: matches main: the only two failures, pypi_poetry::...wire_write_failure... and pypi_requirements::...wire_failure_rolls_back..., fail on unpatched main too when run as root in the agent sandbox.

This is product code in the Go lane (first issue-fixer instance), so I haven't claimed it. The doc comment above same_dir_key should be updated with the fix.


Generated by Claude Code

Activity

  1. mikolalysenko commented on Oct 12, 2026

    @mikolalysenko
    CollaboratorAuthor

    [agent] Open PR #1411 addresses this (normalizes the use path lexically before canonicalizing in same_dir_key). Leaving this open until it merges.


    Generated by Claude Code

  2. mikolalysenko commented on Oct 12, 2026

    @mikolalysenko
    CollaboratorAuthor

    [agent] Fixed on main by #1411 (7437948). same_dir_key (crates/socket-patch-core/src/vendor/go_consumer_sync.rs:477) now falls back to canonicalizing the lexically folded path when the raw join doesn't exist, so ./x/../app resolves to the same key as the project root through a symlinked prefix.

    Checked on main at 7236190 with the issue's Linux repro (TMPDIR pointing at a symlinked dir):

    TMPDIR=/tmp/link cargo test -p socket-patch-core --lib go_consumer_sync
    test result: ok. 10 passed; 0 failed
    

    Closing as completed.


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions