Skip to content

fix(sandbox): report why a sandbox config read failed - #9198

Merged
cv merged 3 commits into
NVIDIA:mainfrom
harjothkhara:oss-find/nemoclaw-2026-08-14
Aug 15, 2026
Merged

fix(sandbox): report why a sandbox config read failed#9198
cv merged 3 commits into
NVIDIA:mainfrom
harjothkhara:oss-find/nemoclaw-2026-08-14

Conversation

@harjothkhara

@harjothkhara harjothkhara commented Aug 15, 2026

Copy link
Copy Markdown
Contributor

Summary

nemoclaw inference set told a reporter "Is the sandbox running?" about a sandbox that was Phase Ready. It says that about every failed config read, because the diagnostic naming the real reason was thrown inside a try whose catch discarded it. This lets that reason reach the user.

Before: Cannot read openclaw config (/sandbox/.openclaw/openclaw.json). / Is the sandbox running? / Start the sandbox and retry.
After: Cannot read openclaw config (/sandbox/.openclaw/openclaw.json): exec session setup failed: container not ready

Related Issue

Refs: #9104

Changes

  • src/lib/sandbox/config.tsreadSandboxConfig runs openshell sandbox exec -- cat <configPath>. On a failed exec it built a diagnostic carrying OpenShell's reason and threw it through configFail, but the enclosing catch { raw = ""; } swallowed it unconditionally, so execution always fell through to the generic stopped-sandbox message below. That made the detailed branch dead code. SandboxConfigError now escapes the catch; unexpected errors still become an empty read.
  • The reason is taken from the spawn error and stderr only. It previously also fell back to result.output, which is stdout-first (captureOutput, adapters/openshell/client.ts:161) — and stdout here is the agent config the cat printed. Surfacing a diagnostic that could carry it would put config contents, credentials included, into a CLI error.
  • When OpenShell reports no reason at all, nothing changes: the read stays empty and the existing "Is the sandbox running?" text stands as the best remaining guess.
  • test/sandbox-config-read-failure-diagnostic.test.ts — new. Drives the real read path (real spawnSync, real captureOpenshellCommand) against a stub OpenShell binary selected with NEMOCLAW_OPENSHELL_BIN.

No new abstraction, configuration, fallback, or compatibility path.

On the exit code, which is the issue's headline

I could not reproduce exit 0, and this PR does not claim to fix it. Driving the real binary with a stub OpenShell whose sandbox exec -- cat fails, both grammars exit 1 on current main:

$ nemoclaw inference set --provider nvidia-prod --model … --sandbox test-sb --no-verify
  Cannot read openclaw config (/sandbox/.openclaw/openclaw.json).
  Is the sandbox running?
  Start the sandbox and retry.
exit=1

The contract holds in source too: configFail throws SandboxConfigError with exit code 1, readInSandboxConfigOrFail carries it into InferenceSetError, and both inference:set and sandbox:inference:set call failWithLines(…, error.exitCode). The three sibling sandbox config commands do the same. No commit has touched these files since v0.0.108, the reported version.

What I did reproduce is the issue's other stated expectation — "the message should say so accurately" — so that is what this fixes. If the reporter can still see exit=0, the wrapper and shell around the invocation are worth capturing, since the CLI itself returns 1 here.

Type of Change

  • Code change (feature, bug fix, or refactor)
  • Code change with doc updates
  • Doc only (prose changes, no code sample modifications)
  • Doc only (includes code sample changes)

Quality Gates

  • Tests added or updated for changed behavior
  • Existing tests cover changed behavior — justification:
  • Tests not applicable — justification:
  • Docs updated for user-facing behavior changes
  • Docs not applicable — justification: no page documents this diagnostic. grep -rn "Is the sandbox running\|Cannot read" docs/ fern/ returns only one unrelated line (docs/reference/commands.mdx:2558, prose about policy presets). No flag, command surface, or documented output changes.
  • Sensitive paths changed (security, policy, credentials, preflight, onboarding, inference, runner, sandbox, or messaging)
  • Sensitive-path review completed or maintainer-approved waiver recorded — reviewer/approval link/justification: requested — this touches the sandbox config read, and the result.output change above is the part worth a second pair of eyes.
  • Non-success, skipped, or missing CI check accepted by maintainer — check name, approval link, and follow-up issue:

Documentation Writer Review

  • Documentation writer subagent reviewed the completed changes
  • Result: no-docs-needed
  • Evidence: Reviewed src/lib/sandbox/config.ts, test/sandbox-config-read-failure-diagnostic.test.ts, linked issue [Ubuntu 24.04][Inference] inference set exits 0 after failing to read the sandbox openclaw config #9104, and the owning inference and sandbox-configuration guides. The merge with current main preserves both reviewed PR-owned blobs. The change replaces an undocumented generic fallback with OpenShell's available stderr or spawn-error diagnostic, preserves the generic fallback when no diagnostic exists, and does not change commands, flags, configuration, defaults, exit behavior, or a documented recovery procedure. No documentation page contains the old fallback or the new transport-specific example, and the diagnostic does not include partial stdout or sandbox configuration content.
  • Agent: Codex Desktop

Verification

  • PR description includes a Signed-off-by: line and every commit appears as Verified in GitHub
  • Normal pre-commit, commit-msg, and pre-push hooks passed, or npm run validate:pr passed after refreshing origin/main when hooks were skipped or unavailable
  • Targeted behavior tests pass for the current change set, or tests are marked not applicable above — command/result: see below
  • Applicable broad gate passed — npm test for broad runtime/test-harness changes; npm run check for repo-wide validation/coverage changes — command/result: not applicable; this is a bounded change to one function, not a runtime or test-harness change.
  • Quality Gates section completed with required justifications or waivers
  • No secrets, API keys, or credentials committed
  • npm run docs builds without warnings (doc changes only)
  • Doc pages follow the style guide (doc changes only)
  • New doc pages include SPDX header and frontmatter (new pages only)

Red, then green

The new test against unmodified origin/main sources (git checkout origin/main -- src/lib/sandbox/config.ts):

 × reports the reason OpenShell gave for the failed read
 × does not blame a stopped sandbox when OpenShell reported another reason
 Tests  2 failed | 1 passed (3)

With the fix:

npx vitest run --project integration test/sandbox-config-read-failure-diagnostic.test.ts
 Test Files  1 passed (1)
      Tests  4 passed (4)

Real behavior, through the real CLI

Stub OpenShell on PATH, isolated HOME, one registered sandbox; sandbox exec -- cat fails with exec session setup failed: container not ready. Only one OpenShell call is made — the read is the pre-flight gate (#6997), so nothing is mutated either way.

$ nemoclaw inference set --provider nvidia-prod --model … --sandbox bug9104-alpha --no-verify

# origin/main
  Cannot read openclaw config (/sandbox/.openclaw/openclaw.json).
  Is the sandbox running?
  Start the sandbox and retry.
exit=1

# this branch
  Cannot read openclaw config (/sandbox/.openclaw/openclaw.json): exec session setup failed: container not ready
exit=1

The "Start the sandbox and retry." hint correctly disappears: readInSandboxConfigOrFail appends it only to a message asking whether the sandbox is running.

Blast radius

readSandboxConfig feeds config get, config set, config rotate-token, inference set, and the tunnel allowed-origins reader. All of them already route SandboxConfigError to a non-zero exit, so each gets the same better diagnostic and nothing else changes. Found by grepping the symbol and the changed literals repo-wide, not by picking adjacent directories.

npx vitest run --project cli src/lib/sandbox/ src/lib/actions/inference-set
 Test Files  35 passed (35)   Tests  403 passed (403)

npx vitest run --project integration \
  test/openclaw-config-transaction-wiring.test.ts test/hermes-config-transaction-wiring.test.ts \
  test/inference-set-preflight.test.ts test/config-set.test.ts test/config-set-prompt-error.test.ts \
  test/config-set-nested-ssrf.test.ts test/policy-mutation-read-failure.test.ts \
  test/openclaw-config-restore.test.ts test/exit-code-user-error-surfaces.test.ts
 Test Files  9 passed (9)    Tests  142 passed (142)

npm run typecheck:cli        # clean
npm run checks:repository    # all checks passed

Limits

  • The reporter's platform is Ubuntu 24.04 with live OpenShell 0.0.101; everything above ran on macOS against a stub OpenShell binary. The failure is in NemoClaw's host-side read, which is platform-independent, but no live sandbox was involved.
  • Exit code 0 is unreproduced, as described above. The issue stays open for it.

Signed-off-by: harjoth harjoth.khara@gmail.com

Summary by CodeRabbit

  • Bug Fixes

    • Improved sandbox configuration error messages by showing relevant command errors or diagnostics without exposing sensitive configuration output.
    • Preserved clearer failure guidance, including accurate messaging for stopped sandboxes.
    • Explicit configuration read failures now report their original error details.
  • Tests

    • Added regression coverage for diagnostic preservation, fallback guidance, and prevention of sensitive output disclosure.

readSandboxConfig raised a diagnostic carrying the reason OpenShell gave
for a failed `sandbox exec -- cat`, but raised it inside a try whose catch
discarded every error. The reason never reached the caller, so every failed
read reported the generic "Is the sandbox running?" text — wrong whenever
the sandbox was running and the exec failed for another reason.

Let that diagnostic reach the caller. When OpenShell reports no reason, the
stopped-sandbox text stays as the best remaining guess.

The reason comes from stderr and the spawn error only. `result.output` is
stdout-first, and stdout here is the config the read printed, so using it
would put config contents into a CLI error.

Refs: NVIDIA#9104
Signed-off-by: harjoth <harjoth.khara@gmail.com>
@copy-pr-bot

copy-pr-bot Bot commented Aug 15, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@coderabbitai

coderabbitai Bot commented Aug 15, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 12750ed3-a4e1-40da-b8c9-05b549761122

📥 Commits

Reviewing files that changed from the base of the PR and between 7b1c064 and 0722614.

📒 Files selected for processing (2)
  • src/lib/sandbox/config.ts
  • test/sandbox-config-read-failure-diagnostic.test.ts

📝 Walkthrough

Walkthrough

Sandbox configuration read failures now report safe error details without exposing stdout contents. Explicit SandboxConfigError failures are preserved. Regression tests verify stderr handling, fallback guidance, and sensitive output redaction.

Changes

Sandbox config diagnostics

Layer / File(s) Summary
Safe config read failure handling
src/lib/sandbox/config.ts, test/sandbox-config-read-failure-diagnostic.test.ts
Config read failures now use command error details or stderr instead of stdout. Successful reads retain exact stdout for hashing. Explicit SandboxConfigError failures are rethrown. Tests verify diagnostics, fallback guidance, and prevention of sensitive stdout leakage.

Estimated code review effort: 2 (Simple) | ~10 minutes

Merge Risk: ⚪ Minimal · up to 07226

This localized change improves failed sandbox-config diagnostics without changing successful behavior or exit-code handling. No actionable merge-blocking risk remains after normal checks and review.

Suggested reviewers: brandonpelfrey

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: reporting specific reasons when sandbox config reads fail.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Aug 15, 2026

Copy link
Copy Markdown
Contributor

PR Review Advisor — No blocking findings reported

Advisor assessment: No blocking advisor findings reported
Next action: No advisor follow-up needed.
Findings: 0 blockers · 0 warnings · 0 suggestions

Model lanes

  • GPT-5.6 Terra (primary): Completed · high confidence · 0 blockers · 0 warnings · 0 suggestions
  • Nemotron 3 Ultra (second opinion): Completed · high confidence · 0 blockers · 0 warnings · 0 suggestions
  • Model comparison: normalized findings match; normalized terminology decisions differ; normalized E2E selections differ; severity counts match.
1 additional E2E selection from the second opinion

Advisory only. The primary lane did not select these E2E jobs or targets.

  • sandbox-operations: The completed second-opinion lane identified E2E coverage that the primary lane omitted.

Second-opinion terminology and E2E selections are advisory. Live E2E does not run automatically for pull requests.

3 semantic terminology decisions

Terminology decisions are advisory. They affect the assessment only when a separate finding identifies concrete semantic impact.

  • justified — diagnostic channels at src/lib/sandbox/config.ts:465: Keep the term because it identifies the restricted sources for diagnostics.
  • justified — stopped-sandbox message at src/lib/sandbox/config.ts:470: Keep the modifier because it distinguishes the generic fallback from a specific read-failure diagnostic.
  • justified — empty reads at src/lib/sandbox/config.ts:481: Keep the term because it distinguishes unexpected capture failures from preserved command diagnostics.

E2E guidance

Advisory only. A maintainer can dispatch the default E2E suite for the commit under review.

Recommended E2E: None

1 optional E2E recommendation
  • openclaw-inference-switch

Workflow run details

This automated review informs maintainers. Warnings and suggestions do not require a response. A maintainer decides whether to merge.

@harjothkhara
harjothkhara marked this pull request as ready for review August 15, 2026 05:58
@senthilr-nv

senthilr-nv commented Aug 15, 2026

Copy link
Copy Markdown
Collaborator

Maintainer gate status: blocked by required CI at latest PR commit 9b63efe.

The behavior-preserving branch refresh and authorized full rerun reproduced the same shard 12 failure in test/skills/triage-runtime.test.ts at lines 158, 177, and 187: each subprocess returned status 1 instead of 0. This is the third required-CI run with the same result. The PR-owned files remain limited to src/lib/sandbox/config.ts and test/sandbox-config-read-failure-diagnostic.test.ts; the focused triage-runtime test passes locally, so I found no evidence that this PR caused the failure.

No contributor change is requested from this result. The existing approval does not satisfy the merge gate while cli-test-shards (12), cli-tests, and aggregate checks are failing.

Evidence: https://github.com/NVIDIA/NemoClaw/actions/runs/31871380586/job/94980992068

@cv cv left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Security review: PASS

Reviewed commit 9eb62a99bf95cfbc7da420a4d7d17c3d54fdf3ba across secrets, input handling, authorization, dependencies, error handling, cryptography, configuration, security tests, and system security. The change propagates process diagnostics without including configuration output. Regression coverage confirms that partial configuration output does not enter the error. No security findings.

@cv
cv merged commit a1ecf39 into NVIDIA:main Aug 15, 2026
57 of 60 checks passed
ericksoa pushed a commit that referenced this pull request Aug 18, 2026
<!-- markdownlint-disable MD041 -->
## Summary

Add the canonical dated changelog entry required before planning the
v0.0.110 release. The entry summarizes user-facing changes merged since
v0.0.109 and links each change to its published documentation route and
source PR.

## Changes

- Add `docs/changelog/2026-08-17.mdx` with the exact `## v0.0.110`
release heading.
- Cover managed local inference, endpoint validation, onboarding and
recovery, explicit experimental Portable OpenClaw, messaging and policy
cleanup, backup and security hardening, and release qualification.
- Preserve the documentation skip list and the current supported-agent
matrix; test-only refactors, dormant activation work, and Pi-only
changes are intentionally excluded.

### Source-to-doc mapping

- #8711 -> `docs/changelog/2026-08-17.mdx`: Add the Muse Glimmer
llama.cpp profile.
- #9099 -> `docs/changelog/2026-08-17.mdx`: Update the Muse Glimmer vLLM
runtime.
- #9319 -> `docs/changelog/2026-08-17.mdx`: Select the provider required
by an explicit serving profile.
- #9311 -> `docs/changelog/2026-08-17.mdx`: Report probe-image pull
failures separately.
- #9345 -> `docs/changelog/2026-08-17.mdx`: Reuse mirrored Windows
Ollama.
- #9284 -> `docs/changelog/2026-08-17.mdx`: Complete the required Ollama
upgrade.
- #9320 -> `docs/changelog/2026-08-17.mdx`: Reject unsafe custom
endpoint URLs before mutation.
- #9119 -> `docs/changelog/2026-08-17.mdx`: Reject unsupported custom
endpoint URL components.
- #9236 -> `docs/changelog/2026-08-17.mdx`: Require native Anthropic
tool-use evidence.
- #9347 -> `docs/changelog/2026-08-17.mdx`: Distinguish Gemini runtime
404 diagnostics.
- #9307 -> `docs/changelog/2026-08-17.mdx`: Preserve the recorded API
family when only the model drifts.
- #9233 -> `docs/changelog/2026-08-17.mdx`: Fail incomplete Hermes route
synchronization.
- #9185 -> `docs/changelog/2026-08-17.mdx`: Serialize Model Router
lifecycle work across gateways.
- #9112 -> `docs/changelog/2026-08-17.mdx`: Stop Model Router after the
last routed sandbox is destroyed.
- #9229 -> `docs/changelog/2026-08-17.mdx`: Verify fresh sandbox
execution readiness.
- #9299 -> `docs/changelog/2026-08-17.mdx`: Verify a separate agent API
host forward before reporting ready.
- #9318 -> `docs/changelog/2026-08-17.mdx`: Honor explicit sandbox
recreation.
- #9325 -> `docs/changelog/2026-08-17.mdx`: Measure readiness reuse
windows from collection completion.
- #9352 -> `docs/changelog/2026-08-17.mdx`: Guide users away from the
deprecated global start command.
- #9370 -> `docs/changelog/2026-08-17.mdx`: Persist managed OpenClaw
agent identity.
- #9366 -> `docs/changelog/2026-08-17.mdx`: Pass messaging dependencies
during reused onboarding.
- #9321 -> `docs/changelog/2026-08-17.mdx`: Detect proxied connect
sessions.
- #9285 -> `docs/changelog/2026-08-17.mdx`: Run probe-only recovery when
absent authority cannot be created.
- #9282 -> `docs/changelog/2026-08-17.mdx`: Complete probe-only recovery
without platform evidence.
- #8920 -> `docs/changelog/2026-08-17.mdx`: Preserve legacy gateway
identity.
- #9198 -> `docs/changelog/2026-08-17.mdx`: Report sandbox config-read
failures.
- #9201 -> `docs/changelog/2026-08-17.mdx`: Remove only the exact Docker
orphan on destroy.
- #9176 -> `docs/changelog/2026-08-17.mdx`: Use rootless Podman for
Portable lifecycle operations.
- #9197 -> `docs/changelog/2026-08-17.mdx`: Preflight Portable CPU
delegation.
- #9289 -> `docs/changelog/2026-08-17.mdx`: Narrow Portable policy
defaults.
- #9270 -> `docs/changelog/2026-08-17.mdx`: Preserve Portable model
intent.
- #9339 -> `docs/changelog/2026-08-17.mdx`: Reconcile timed-out Portable
stop state.
- #9209 -> `docs/changelog/2026-08-17.mdx`: Clean receipt-owned Portable
Podman resources.
- #9186 -> `docs/changelog/2026-08-17.mdx`: Separate Podman activation
readiness.
- #9376 -> `docs/changelog/2026-08-17.mdx`: Settle Portable OpenClaw
pairing before readiness.
- #9296 -> `docs/changelog/2026-08-17.mdx`: Retire messaging channel
presets the host no longer configures.
- #9327 -> `docs/changelog/2026-08-17.mdx`: Drop retired channels from
reused messaging selections.
- #9306 -> `docs/changelog/2026-08-17.mdx`: Remove gateway-enforced
presets without a local record.
- #9248 -> `docs/changelog/2026-08-17.mdx`: Activate Google Chat pairing
approval.
- #9374 -> `docs/changelog/2026-08-17.mdx`: Accept schema-owned
messaging plan fields.
- #9317 -> `docs/changelog/2026-08-17.mdx`: Accept safe hard-linked
package files during backup.
- #9288 -> `docs/changelog/2026-08-17.mdx`: Remove managed CLI shims
with destroyed user data.
- #9239 -> `docs/changelog/2026-08-17.mdx`: Read voice credentials from
fixed descriptors.
- #9269 -> `docs/changelog/2026-08-17.mdx`: Accept bounded native
OpenClaw device modes.
- #9371 -> `docs/changelog/2026-08-17.mdx`: Isolate OpenClaw
startup-guard output.
- #9351 -> `docs/changelog/2026-08-17.mdx`: Restore staging Launchable
validation.
- #9350 -> `docs/changelog/2026-08-17.mdx`: Retry transient
collaborator-permission reads.
- #9353 -> `docs/changelog/2026-08-17.mdx`: Retry transient
exact-artifact downloads.
- #9226 -> `docs/changelog/2026-08-17.mdx`: Add bounded Brev readiness
diagnostics.
- #9237 -> `docs/changelog/2026-08-17.mdx`: Report same-commit E2E
reliability.
- #9232 -> `docs/changelog/2026-08-17.mdx`: Execute native-runtime
qualification.
- #9275 -> `docs/changelog/2026-08-17.mdx`: Define E2E selection and
retry guidance.
- #9234 -> `docs/changelog/2026-08-17.mdx`: Move documentation review
after merge.
- #9365 -> `docs/changelog/2026-08-17.mdx`: Mount documentation reviewer
inputs before startup.

## Type of Change

- [ ] Code change (feature, bug fix, or refactor)
- [ ] Code change with doc updates
- [x] Doc only (prose changes, no code sample modifications)
- [ ] Doc only (includes code sample changes)

## Quality Gates

- [ ] Tests added or updated for changed behavior
- [x] Existing tests cover changed behavior — justification:
`test/changelog-docs.test.ts` validates the dated release-entry
contract.
- [ ] Tests not applicable — justification:
- [ ] Sensitive paths changed (security, policy, credentials, preflight,
onboarding, inference, runner, sandbox, or messaging)
- [ ] Sensitive-path review completed or maintainer-approved waiver
recorded — reviewer/approval link/justification:
- [ ] Non-success, skipped, or missing CI check accepted by maintainer —
check name, approval link, and follow-up issue:

## DGX Station Hardware Evidence

- [ ] Tested on DGX Station
- Tested commit: Not applicable; documentation-only change.
- Station profile/scenario: Not applicable.
- Result: Not applicable.
- Supporting evidence: Not applicable.

## Verification

- [x] PR description includes a `Signed-off-by:` line and every commit
appears as `Verified` in GitHub
- [x] Normal `pre-commit`, `commit-msg`, and `pre-push` hooks passed, or
`npm run validate:pr` passed after refreshing `origin/main` when hooks
were skipped or unavailable
- [x] Targeted behavior tests pass for the current change set, or tests
are marked not applicable above — `npx vitest run
test/changelog-docs.test.ts` (7 passed)
- [x] Applicable broad gate passed — `npm test` for broad
runtime/test-harness changes; `npm run check` for repo-wide
validation/coverage changes — command/result: Not applicable to one
prose-only changelog page; `npm run docs` passed the repository's strict
documentation gate.
- [x] Quality Gates section completed with required justifications or
waivers
- [x] No secrets, API keys, or credentials committed
- [ ] `npm run docs` builds without warnings (doc changes only) — passed
with 0 errors and the 2 existing Fern warnings.
- [x] Doc pages follow the [style
guide](https://github.com/NVIDIA/NemoClaw/blob/main/docs/CONTRIBUTING.md)
(doc changes only)
- [ ] New doc pages include SPDX header and frontmatter (new pages only)
— the SPDX header is present; dated changelog pages intentionally do not
use frontmatter.

---
Signed-off-by: Charan Jagwani <cjagwani@nvidia.com>


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Documentation**
  * Added release notes for v0.0.110.
* Documented experimental managed llama.cpp and Portable OpenClaw
profiles.
* Covered inference validation, onboarding and recovery improvements,
rootless lifecycle handling, messaging and policy updates, backups,
credential handling, filesystem protections, and release qualification
updates.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
@wscurran wscurran added the bug-fix PR fixes a bug or regression label Aug 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug-fix PR fixes a bug or regression

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants