• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

pantsbuild / pants / 25951830241 / 9
93%
main: 93%

Build:
Build:
LAST BUILD BRANCH: fix-subsystem-mypy-plugin
DEFAULT BRANCH: main
Ran 16 May 2026 04:15AM UTC
Files 1226
Run time 30s
Badge
Embed ▾
README BADGES
x

If you need to use a raster PNG badge, change the '.svg' to '.png' in the link

Markdown

Textile

RDoc

HTML

Rst

16 May 2026 03:39AM UTC coverage: 59.456% (-0.001%) from 59.457%
25951830241.9

push

github

web-flow
Fix: IntrinsicError when a non-directory PATH entry is used with `system_binary` (Cherry-pick of #23327) (#23353)

Closes #21990

## Problem

Pants crashed with `IntrinsicError: Not a directory (os error 20)` when
a
`system_binary` target (or any binary lookup) included a non-directory
entry in
its search path. Two distinct shapes of the same underlying bug:

1. **`foo/bar` on PATH where `foo` is a file**. Calling
`path_metadata_request`
on `foo/bar` hits `ENOTDIR` in the OS. That error was not caught in the
Rust
   layer, so it surfaced as an uncaught `IntrinsicError`.

2. **A symlink-to-file on PATH** — the case from the issue report. The
first
`path_metadata_request` succeeds and returns
`PathMetadataKind::SYMLINK`,
but the Python code then tried to look up `symlink/binary_name`, which
also
   hits `ENOTDIR`.

## Fix

**`src/rust/fs/src/posixfs.rs`** — `path_metadata` now accepts a
`follow_symlinks`
flag. When `true`, it calls `tokio::fs::metadata` (which follows
symlinks) instead
of `tokio::fs::symlink_metadata`, so a symlink-to-directory appears as a
`Directory` rather than a `Symlink`. It also continues to treat
`ENOTDIR` as absent
(`Ok(None)`), fixing the file-component-on-PATH crash.

**`src/rust/fs/src/lib.rs`** — The `Vfs` trait's `path_metadata`
signature is
updated to accept `follow_symlinks: bool`. The in-memory `DigestTrie`
implementation
accepts but ignores the flag.

**`src/rust/engine/src/nodes/path_metadata.rs`** — `PathMetadataNode`
now carries
`follow_symlinks` and passes it through to the VFS call.

**`src/rust/engine/src/intrinsics/digests.rs`** — The
`path_metadata_request`
intrinsic reads `follow_symlinks` from the Python `PathMetadataRequest`
object and
passes it to `PathMetadataNode`.

**`src/python/pants/engine/fs.py`** — `PathMetadataRequest` gains a
`follow_symlinks: bool = False` field.

**`src/python/pants/core/util_rules/system_binaries.py`** — The initial
lookup of
each PATH entry uses `follow_symlinks=True`. A symlink... (continued)

38184 of 64222 relevant lines covered (59.46%)

0.59 hits per line

Source Files on job test_python_linux_x86_64_4/10 - 25951830241.9
  • Tree
  • List 1226
  • Changed 3
  • Source Changed 2
  • Coverage Changed 3
Coverage ∆ File Lines Relevant Covered Missed Hits/Line
  • Back to Build 25951830241
  • c0f83925 on github
  • Prev Job for on 2.32.x (#25869747091.8)
  • Next Job for on 2.32.x (#25989245395.6)
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc