Summary
The Test (x86_64) (nightly) CI leg started failing on every PR (not just
this one) around 2026-07-31 ~02:48 UTC, in tests/dsv_cli_tests.rs,
tests/text_cli_tests.rs, tests/json_validate_tests.rs, and
tests/yaml_validate_tests.rs. All four share a succinctly_bin() helper that
locates the pre-built succinctly CLI binary by walking up from the test
executable's own std::env::current_exe() path, popping a deps/ component
if present. That assumption broke because nightly Cargo just defaulted to a
new build-directory layout.
Example failure (PR #504):
thread 'bare_header_flag_still_accepted' panicked at tests/dsv_cli_tests.rs:45:9:
built `succinctly` binary not found at /home/runner/work/succinctly/succinctly/target/debug/build/succinctly/e4276bf48fd0cf8f/out/succinctly
Observed on:
Root cause
Cargo's nightly toolchain defaulted -Zbuild-dir-new-layout to on
(rust-lang/cargo#17258, tracking issue rust-lang/cargo#16147, announced in
"Call for Testing: Build Dir Layout v2").
It reorganizes intermediate build artifacts — including test binaries — by
package name and build-unit hash instead of the old flat deps/ directory:
- Old:
target/<profile>/deps/<test>-<hash>
- New:
target/<profile>/build/<pkg>/<hash>/out/<test>-<hash>
Because dtolnay/rust-toolchain@master with toolchain: nightly always pulls
the latest nightly, every PR's advisory nightly leg started hitting this the
moment the default flipped upstream — no code or CI-config change in this repo
triggered it. The Cargo team's own write-up on the failure mode: tools that
infer a binary's location from a test's current_exe() need to stop assuming
the flat layout; use CARGO_BIN_EXE_* where possible instead (not usable
here — see "Why not CARGO_BIN_EXE_succinctly" below).
Why it doesn't block merges (but will keep failing until fixed)
.github/workflows/ci.yml runs nightly under
continue-on-error: ${{ matrix.rust == 'nightly' }} — it's advisory, not a
required status check, so no PR is blocked. However, since nightly's default
has flipped upstream (not a transient blip), every PR's nightly leg will
keep failing until the test helpers are fixed, permanently show a red X on
an otherwise-passing run, and mask any real nightly-only regression this leg
exists to catch.
Why not CARGO_BIN_EXE_succinctly
The integration-test harness is compiled without the cli feature (CI runs
plain cargo test), and the succinctly binary is gated by
required-features = ["cli"], so CARGO_BIN_EXE_succinctly is never set.
That's why these tests build the CLI binary once via a cargo build --features cli --bin succinctly subprocess and locate it manually — the fix needs to
keep doing that, just compute the resulting path correctly under both layouts.
Fix
Already implemented on branch issue-476-jq-del-errors-when-a-deleted-key-s-container
(commit d7ee7ec0, part of PR #504): replace the pop() / "if last component
is deps, pop again" heuristic with a helper that locates target/<profile>/
by finding the target path component in current_exe() and taking the
component immediately after it as the profile directory. That component is
<profile> (e.g. debug) under both the old flat layout and the new nested
one, so it's layout-agnostic:
fn target_profile_dir_from_test_exe() -> PathBuf {
let current_exe = std::env::current_exe().expect("resolve current_exe");
let components: Vec<_> = current_exe.components().collect();
let target_idx = components
.iter()
.rposition(|c| c.as_os_str() == "target")
.expect("test executable path has no `target` component");
components[..=target_idx + 1].iter().collect()
}
Verified locally: all 4 suites pass (cargo test --test dsv_cli_tests --test text_cli_tests --test json_validate_tests --test yaml_validate_tests),
cargo clippy --features cli -- -D warnings is clean, cargo fmt --check is
clean.
Affected files
tests/dsv_cli_tests.rs
tests/text_cli_tests.rs
tests/json_validate_tests.rs
tests/yaml_validate_tests.rs
Summary
The
Test (x86_64) (nightly)CI leg started failing on every PR (not justthis one) around 2026-07-31 ~02:48 UTC, in
tests/dsv_cli_tests.rs,tests/text_cli_tests.rs,tests/json_validate_tests.rs, andtests/yaml_validate_tests.rs. All four share asuccinctly_bin()helper thatlocates the pre-built
succinctlyCLI binary by walking up from the testexecutable's own
std::env::current_exe()path, popping adeps/componentif present. That assumption broke because nightly Cargo just defaulted to a
new build-directory layout.
Example failure (PR #504):
Observed on:
issue-484-..., run30600056489) hit the identical failure at nearly the same timestamp, confirming this is a toolchain change, not something specific to one branch's code.Root cause
Cargo's nightly toolchain defaulted
-Zbuild-dir-new-layoutto on(rust-lang/cargo#17258, tracking issue rust-lang/cargo#16147, announced in
"Call for Testing: Build Dir Layout v2").
It reorganizes intermediate build artifacts — including test binaries — by
package name and build-unit hash instead of the old flat
deps/directory:target/<profile>/deps/<test>-<hash>target/<profile>/build/<pkg>/<hash>/out/<test>-<hash>Because
dtolnay/rust-toolchain@masterwithtoolchain: nightlyalways pullsthe latest nightly, every PR's advisory nightly leg started hitting this the
moment the default flipped upstream — no code or CI-config change in this repo
triggered it. The Cargo team's own write-up on the failure mode: tools that
infer a binary's location from a test's
current_exe()need to stop assumingthe flat layout; use
CARGO_BIN_EXE_*where possible instead (not usablehere — see "Why not
CARGO_BIN_EXE_succinctly" below).Why it doesn't block merges (but will keep failing until fixed)
.github/workflows/ci.ymlruns nightly undercontinue-on-error: ${{ matrix.rust == 'nightly' }}— it's advisory, not arequired status check, so no PR is blocked. However, since nightly's default
has flipped upstream (not a transient blip), every PR's nightly leg will
keep failing until the test helpers are fixed, permanently show a red X on
an otherwise-passing run, and mask any real nightly-only regression this leg
exists to catch.
Why not
CARGO_BIN_EXE_succinctlyThe integration-test harness is compiled without the
clifeature (CI runsplain
cargo test), and thesuccinctlybinary is gated byrequired-features = ["cli"], soCARGO_BIN_EXE_succinctlyis never set.That's why these tests build the CLI binary once via a
cargo build --features cli --bin succinctlysubprocess and locate it manually — the fix needs tokeep doing that, just compute the resulting path correctly under both layouts.
Fix
Already implemented on branch
issue-476-jq-del-errors-when-a-deleted-key-s-container(commit
d7ee7ec0, part of PR #504): replace thepop()/ "if last componentis
deps, pop again" heuristic with a helper that locatestarget/<profile>/by finding the
targetpath component incurrent_exe()and taking thecomponent immediately after it as the profile directory. That component is
<profile>(e.g.debug) under both the old flat layout and the new nestedone, so it's layout-agnostic:
Verified locally: all 4 suites pass (
cargo test --test dsv_cli_tests --test text_cli_tests --test json_validate_tests --test yaml_validate_tests),cargo clippy --features cli -- -D warningsis clean,cargo fmt --checkisclean.
Affected files
tests/dsv_cli_tests.rstests/text_cli_tests.rstests/json_validate_tests.rstests/yaml_validate_tests.rs