Skip to content

fix(config): make config auto-discovery skip the same errors on every platform#34558

Merged
littledivy merged 1 commit into
mainfrom
orch/divybot-304
May 30, 2026
Merged

fix(config): make config auto-discovery skip the same errors on every platform#34558
littledivy merged 1 commit into
mainfrom
orch/divybot-304

Conversation

@divybot

@divybot divybot commented May 30, 2026

Copy link
Copy Markdown
Contributor

Fixes #17428

Summary

is_skippable_io_error (the helper that decides which IO errors silently get skipped while walking ancestors for a deno.json/deno.jsonc) previously gated its checks on cfg!(windows) / cfg!(unix) and raw errno comparisons:

if cfg!(windows) && e.raw_os_error() == Some(123) { return true; } // ERROR_INVALID_NAME
match e.kind() {
  InvalidInput | PermissionDenied | NotFound => true,
  _ => cfg!(unix) && e.raw_os_error() == Some(20), // ENOTDIR
}

The same logical condition — a non-directory parent component on the way to deno.json, an invalid filename, a directory that happens to be named deno.json — maps to different errors on Linux vs. Windows. The function returned true on one platform and false on the other for what was effectively the same situation, causing discovery to abort on one OS and silently continue on the other. That is the inconsistency reported in #17428 — a test passing on Windows because the walk-up found a config file, while the same test on Ubuntu failed to find one (or vice versa).

Match on the now-stable ErrorKind variants directly:

matches!(
  e.kind(),
  InvalidInput | InvalidFilename | PermissionDenied
    | NotFound  | NotADirectory   | IsADirectory,
)

NotADirectory/IsADirectory are stable since Rust 1.83 and InvalidFilename since 1.87. The toolchain pinned in rust-toolchain.toml is 1.95.0, so all three are available. Behavior is now identical on every OS.

Test plan

  • cargo test -p deno_config util:: — existing is_skippable_io_error_win_invalid_filename still asserts errno 123 is skippable, added a Unix twin for errno 20, and added a portable is_skippable_io_error_kinds that asserts the expanded ErrorKind set is skipped on every platform (and that unrelated kinds like ConnectionRefused/UnexpectedEof are not).
  • cargo check -p deno_config, cargo clippy -p deno_config --no-deps, cargo check --bin deno — all clean.

Closes denoland/divybot#304

… platform

`is_skippable_io_error` previously used `cfg!(windows)` / `cfg!(unix)` and raw
errno comparisons (`ERROR_INVALID_NAME = 123`, `ENOTDIR = 20`) to decide which
IO errors should be silently skipped while walking ancestors for a
`deno.json`/`deno.jsonc`. The same logical condition (e.g. a non-directory
parent component, an invalid path, a directory named `deno.json`) maps to
different errors on the two platforms, so the function returned `true` for
some failures on one OS and `false` for the same logical failure on the
other. Discovery would abort on one platform and silently continue on the
other, producing different config-detection results across CI runners.

Match on the now-stable `ErrorKind` variants directly so both platforms agree
— `NotADirectory`/`IsADirectory` (stable in 1.83) and `InvalidFilename`
(stable in 1.87) cover the platform-specific raw errno cases. The Rust
toolchain pinned in `rust-toolchain.toml` is 1.95.0.

Closes denoland/orchid#304

Co-Authored-By: Divy Srivastava <[email protected]>
@littledivy
littledivy enabled auto-merge (squash) May 30, 2026 03:50
@littledivy
littledivy merged commit 1250f76 into main May 30, 2026
137 checks passed
@littledivy
littledivy deleted the orch/divybot-304 branch May 30, 2026 04:00
littledivy added a commit to crowlKats/deno that referenced this pull request Jun 10, 2026
… platform (denoland#34558)

## Summary

`is_skippable_io_error` (the helper that decides which IO errors
silently get skipped while walking ancestors for a
`deno.json`/`deno.jsonc`) previously gated its checks on `cfg!(windows)`
/ `cfg!(unix)` and raw errno comparisons:

```rust
if cfg!(windows) && e.raw_os_error() == Some(123) { return true; } // ERROR_INVALID_NAME
match e.kind() {
  InvalidInput | PermissionDenied | NotFound => true,
  _ => cfg!(unix) && e.raw_os_error() == Some(20), // ENOTDIR
}
```

The same logical condition — a non-directory parent component on the way
to `deno.json`, an invalid filename, a directory that happens to be
named `deno.json` — maps to different errors on Linux vs. Windows. The
function returned `true` on one platform and `false` on the other for
what was effectively the same situation, causing discovery to abort on
one OS and silently continue on the other. That is the inconsistency
reported in denoland#17428 — a test passing on Windows because the walk-up found
a config file, while the same test on Ubuntu failed to find one (or vice
versa).

Match on the now-stable `ErrorKind` variants directly:

```rust
matches!(
  e.kind(),
  InvalidInput | InvalidFilename | PermissionDenied
    | NotFound  | NotADirectory   | IsADirectory,
)
```

`NotADirectory`/`IsADirectory` are stable since Rust 1.83 and
`InvalidFilename` since 1.87. The toolchain pinned in
`rust-toolchain.toml` is 1.95.0, so all three are available. Behavior is
now identical on every OS.

## Test plan

- [x] `cargo test -p deno_config util::` — existing
`is_skippable_io_error_win_invalid_filename` still asserts errno 123 is
skippable, added a Unix twin for errno 20, and added a portable
`is_skippable_io_error_kinds` that asserts the expanded `ErrorKind` set
is skipped on every platform (and that unrelated kinds like
`ConnectionRefused`/`UnexpectedEof` are not).
- [x] `cargo check -p deno_config`, `cargo clippy -p deno_config
--no-deps`, `cargo check --bin deno` — all clean.

Closes denoland/orchid#304

Co-authored-by: divybot <[email protected]>
Co-authored-by: Divy Srivastava <[email protected]>
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.

inconsistent config detection between windows & ubuntu

2 participants