ci: fix EXDEV error in fuzz-smoke rustup nightly install#113
Conversation
Set RUSTUP_HOME=/tmp/rustup and CARGO_HOME=/tmp/cargo so rustup temp files and toolchains are on the same filesystem. Without this, `rustup toolchain install nightly` fails with "Invalid cross-device link (os error 18)" on ephemeral runners where /home/runner/.rustup (hostPath cache volume) and /tmp (overlay) are different mounts. Same fix applied to cachekit-rs CI in 2026-03.
📝 WalkthroughWalkthroughPins Rust nightly to nightly-2026-04-27 and sets RUSTUP_HOME/CARGO_HOME to /tmp in the fuzz-smoke workflow; updates the fuzz crate to depend on cachekit-core =0.1.1; reduces/adjusts FUZZ_TARGETS and the cargo fuzz invocation; and switches CI test job Redis startup to an explicit docker run that waits for PONG. ChangesFuzz workflow and crate changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related issues
Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
cargo-fuzz 0.13.1 depends on rustix which uses internal rustc_layout_scalar_valid_range_* attributes. Nightly 1.97.0 (2026-05-14+) reserved these attributes, breaking compilation. Pin to last known-good nightly until cargo-fuzz ships a fix.
- rust/fuzz/Cargo.toml: depend on cachekit-core directly (the fuzz targets use its internal module paths, not the PyO3 wrapper's re-exports). The old cachekit-storage package name no longer exists. - Reduce fuzz target list to 4 that compile against cachekit-core 0.1.1. 9 targets have stale API calls (encrypt_aes_gcm etc.). Tracked in #114. - Use pinned nightly toolchain name in cargo +nightly-2026-04-27.
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
.github/workflows/fuzz-smoke.yml (1)
115-115:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winUpdate the target count to reflect the reduced set.
The message still says "14 targets" but the workflow now runs only 4 fuzz targets (per lines 57-62).
📊 Proposed fix
- echo "Status: All fuzz targets passed (14 targets, 60s each)" + echo "Status: All fuzz targets passed (4 targets, 60s each)"🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/fuzz-smoke.yml at line 115, The status echo still reports "14 targets" but the workflow now runs only 4 fuzz targets; update the echo statement that currently reads 'Status: All fuzz targets passed (14 targets, 60s each)' to reflect the new count (e.g., '4 targets') so the message matches the set defined in the fuzz target steps referenced around the fuzz target declarations; ensure the time-per-target value remains correct if unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In @.github/workflows/fuzz-smoke.yml:
- Line 115: The status echo still reports "14 targets" but the workflow now runs
only 4 fuzz targets; update the echo statement that currently reads 'Status: All
fuzz targets passed (14 targets, 60s each)' to reflect the new count (e.g., '4
targets') so the message matches the set defined in the fuzz target steps
referenced around the fuzz target declarations; ensure the time-per-target value
remains correct if unchanged.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: ef068be5-834c-4480-a640-c33c14abfccc
📒 Files selected for processing (2)
.github/workflows/fuzz-smoke.ymlrust/fuzz/Cargo.toml
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/ci.yml:
- Around line 72-77: The readiness loop using "until docker exec redis redis-cli
ping | grep -q PONG" is unbounded and can hang CI; modify the script that
follows "docker run -d --name redis -p 6379:6379 \ redis:7-alpine ..." to bound
the wait by replacing the raw until loop with a retry/timed loop (e.g., a
for/while loop with a MAX_ATTEMPTS or a timeout in seconds), break early on
success, and exit non‑zero with a clear error message if the ping never succeeds
(so the job fails fast instead of spinning indefinitely).
In @.github/workflows/fuzz-smoke.yml:
- Around line 36-40: The workflow pins a specific nightly via the rustup
commands ("rustup toolchain install nightly-2026-04-27" and "rustup default
nightly-2026-04-27") because cargo-fuzz 0.13.1 pulls in rustix which uses the
removed rustc_layout_scalar_valid_range_* attributes; monitor cargo-fuzz (and
rustix) releases for a version that removes or replaces that dependency and,
when available, drop the nightly pin by removing those rustup lines and
reverting to the project’s normal toolchain selection so the workflow no longer
depends on a time‑boxed nightly.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 9509c758-c18f-4001-8092-0428638f07e8
📒 Files selected for processing (2)
.github/workflows/ci.yml.github/workflows/fuzz-smoke.yml
| - name: Start Redis (no persistence) | ||
| run: | | ||
| docker run -d --name redis -p 6379:6379 \ | ||
| redis:7-alpine redis-server --save "" --appendonly no | ||
| until docker exec redis redis-cli ping | grep -q PONG; do sleep 1; done | ||
|
|
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# First, let's check if the file exists and read the relevant section
if [ -f ".github/workflows/ci.yml" ]; then
echo "=== File exists: .github/workflows/ci.yml ==="
echo "=== Lines 70-80 ==="
sed -n '70,80p' .github/workflows/ci.yml | cat -n
else
echo "File not found. Searching for workflow files..."
fd -e yml -e yaml | head -20
fiRepository: cachekit-io/cachekit-py
Length of output: 638
🏁 Script executed:
# Let's examine the full workflow file to check for any timeout settings or other safeguards
echo "=== Full CI workflow (first 50 lines) ==="
head -50 .github/workflows/ci.yml | cat -n
echo ""
echo "=== Checking for timeout configurations ==="
grep -n "timeout" .github/workflows/ci.yml
echo ""
echo "=== Checking the full 'Start Redis' step context ==="
sed -n '70,85p' .github/workflows/ci.yml | cat -nRepository: cachekit-io/cachekit-py
Length of output: 2418
🏁 Script executed:
# Let's find which job contains this Redis step and verify its timeout
echo "=== Looking for the job that contains the Redis step (around lines 55-80) ==="
sed -n '55,80p' .github/workflows/ci.yml | cat -n
echo ""
echo "=== Checking lines around line 60 for job definition ==="
sed -n '55,65p' .github/workflows/ci.yml | cat -nRepository: cachekit-io/cachekit-py
Length of output: 1710
🏁 Script executed:
# Let's verify the suggested fix syntax is valid for the shell context
# GitHub Actions uses bash by default, so let's check if the syntax is correct
echo "=== Testing the proposed loop syntax ==="
cat << 'EOF' > /tmp/test_syntax.sh
#!/bin/bash
# This tests if the suggested syntax would work
# Simulate what the suggested fix would do
for i in {1..60}; do
echo "Iteration $i"
if [ $i -eq 3 ]; then
echo "Would break here"
break
fi
sleep 0.1
done
# The second part of the suggested fix
echo "After loop"
EOF
bash -n /tmp/test_syntax.sh && echo "✓ Syntax is valid" || echo "✗ Syntax error"
echo ""
echo "=== Examining the actual behavior of the current unbounded loop ==="
echo "If docker run fails OR Redis crashes, the 'until' loop will:"
echo "1. Keep running 'docker exec redis redis-cli ping' indefinitely"
echo "2. Fail at each iteration but continue"
echo "3. Not exit until the job timeout (15 minutes)"
echo "4. The actual error (container not running) gets hidden"Repository: cachekit-io/cachekit-py
Length of output: 462
Bound the Redis readiness loop to prevent hang-on-failure.
The until loop on line 76 is unbounded. If the container fails to start or exits early, it will spin indefinitely until the 15-minute job timeout, obscuring the actual failure and wasting CI time across all test runs.
Suggested fix
- name: Start Redis (no persistence)
run: |
docker run -d --name redis -p 6379:6379 \
redis:7-alpine redis-server --save "" --appendonly no
- until docker exec redis redis-cli ping | grep -q PONG; do sleep 1; done
+ for i in {1..60}; do
+ if docker exec redis redis-cli ping 2>/dev/null | grep -q PONG; then
+ break
+ fi
+ if ! docker ps --filter "name=^redis$" --filter "status=running" | grep -q redis; then
+ echo "Redis container is not running"
+ docker logs redis || true
+ exit 1
+ fi
+ sleep 1
+ done
+ docker exec redis redis-cli ping | grep -q PONG || { echo "Redis did not become ready in time"; docker logs redis || true; exit 1; }📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| - name: Start Redis (no persistence) | |
| run: | | |
| docker run -d --name redis -p 6379:6379 \ | |
| redis:7-alpine redis-server --save "" --appendonly no | |
| until docker exec redis redis-cli ping | grep -q PONG; do sleep 1; done | |
| - name: Start Redis (no persistence) | |
| run: | | |
| docker run -d --name redis -p 6379:6379 \ | |
| redis:7-alpine redis-server --save "" --appendonly no | |
| for i in {1..60}; do | |
| if docker exec redis redis-cli ping 2>/dev/null | grep -q PONG; then | |
| break | |
| fi | |
| if ! docker ps --filter "name=^redis$" --filter "status=running" | grep -q redis; then | |
| echo "Redis container is not running" | |
| docker logs redis || true | |
| exit 1 | |
| fi | |
| sleep 1 | |
| done | |
| docker exec redis redis-cli ping | grep -q PONG || { echo "Redis did not become ready in time"; docker logs redis || true; exit 1; } |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/ci.yml around lines 72 - 77, The readiness loop using
"until docker exec redis redis-cli ping | grep -q PONG" is unbounded and can
hang CI; modify the script that follows "docker run -d --name redis -p 6379:6379
\ redis:7-alpine ..." to bound the wait by replacing the raw until loop with a
retry/timed loop (e.g., a for/while loop with a MAX_ATTEMPTS or a timeout in
seconds), break early on success, and exit non‑zero with a clear error message
if the ping never succeeds (so the job fails fast instead of spinning
indefinitely).
| run: | | ||
| # Pin nightly: cargo-fuzz 0.13.1 → rustix uses rustc_layout_scalar_valid_range_* | ||
| # attributes reserved after nightly-2026-04-27. Last known-good date. | ||
| rustup toolchain install nightly-2026-04-27 | ||
| rustup default nightly-2026-04-27 |
There was a problem hiding this comment.
🧩 Analysis chain
🌐 Web query:
Is Rust nightly-2026-04-27 currently available for download?
💡 Result:
Yes, the Rust nightly toolchain for 2026-04-27 is available [1]. You can install this specific version using the rustup toolchain manager by running the following command in your terminal: rustup toolchain install nightly-2026-04-27 This command instructs rustup to download and install the nightly compiler release corresponding to that specific date [2][3][4]. Once installed, you can use it by referencing the toolchain name directly (e.g., rustup run nightly-2026-04-27 cargo build) or by setting it as an override for a specific project directory [2][3]. Note that nightly toolchains are generated daily, and while a build exists for 2026-04-27 [1], it is possible for some nightly builds to be missing certain non-default components (such as clippy or rust-docs) depending on the build status for that day [5]. If you encounter issues with missing components, you can try using the --profile=minimal flag or check the build status via the rustup-components-history project [5].
Citations:
- 1: rust-lang/rust@3b6080c
- 2: https://rust-lang.github.io/rustup/concepts/channels.html?highlight=nightl
- 3: https://tureus.github.io/rust/2015/11/16/rustup-tutorial-downgrading.html
- 4: https://rust-lang.github.io/rustup/concepts/toolchains.html
- 5: https://rust-lang.github.io/rustup/concepts/channels.html
🌐 Web query:
Does cargo-fuzz 0.13.1 have a known issue with rustix and rustc_layout_scalar_valid_range attributes in Rust nightly builds after April 2026?
💡 Result:
Yes, cargo-fuzz 0.13.1 has a known issue with Rust nightly builds from May 2026 [1]. This issue arises because the Rust compiler removed support for the internal rustc_layout_scalar_valid_range_* attributes [2][3][4], which were previously used by dependencies like rustix [1]. As of May 2026, the Rust compiler has fully deprecated and removed these internal attributes in favor of new pattern types [2][3][5]. Because cargo-fuzz 0.13.1 relies on older versions of its dependencies (such as rustix) that still utilize these now-removed attributes, the crate fails to compile on recent nightly toolchains [1]. Users encountering this error are advised to check for updates to cargo-fuzz or its dependencies that have migrated away from these internal compiler attributes [1].
Citations:
- 1:
cargo install --locked cargo-fuzzfails to install with current rust nightly (rustc 1.97.0-nightly (cb40c25f6 2026-05-04)) rust-fuzz/cargo-fuzz#442 - 2: Stop using rustc_layout_scalar_valid_range_* in rustc rust-lang/rust#152569
- 3: rust-lang/rust@11d88ee
- 4: rust-lang/rust@8882bf0
- 5: Replace
rustc_layout_scalar_valid_range_startattribute with pattern types rust-lang/rust#135996
Monitor for cargo-fuzz updates to resolve rustix compatibility and remove nightly pin.
The pinned nightly (2026-04-27) is ~19 days old. Rust nightlies are retained for ~90 days before expiring on distribution servers. Once this nightly expires, the workflow will fail. The pin exists because cargo-fuzz 0.13.1 depends on rustix, which uses the now-removed rustc_layout_scalar_valid_range_* internal compiler attributes. Track updates to cargo-fuzz that resolve this dependency issue, allowing migration away from a pinned nightly.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/fuzz-smoke.yml around lines 36 - 40, The workflow pins a
specific nightly via the rustup commands ("rustup toolchain install
nightly-2026-04-27" and "rustup default nightly-2026-04-27") because cargo-fuzz
0.13.1 pulls in rustix which uses the removed rustc_layout_scalar_valid_range_*
attributes; monitor cargo-fuzz (and rustix) releases for a version that removes
or replaces that dependency and, when available, drop the nightly pin by
removing those rustup lines and reverting to the project’s normal toolchain
selection so the workflow no longer depends on a time‑boxed nightly.
Sets RUSTUP_HOME and CARGO_HOME to /tmp to avoid cross-device link errors on ephemeral runners. Same fix applied to cachekit-rs in 2026-03.
Summary by CodeRabbit