Conversation
…dbox diagnostics AllowedPaths warnings are flushed to r.stderr during Runner construction. For library callers (e.g. PAR) that surface r.stderr in structured output, this means every script execution in a session ends up with a non-empty stderr whenever the configured allowlist contains a path that does not exist on the host (e.g. /var/log on Windows), even though exitCode is 0 — making the result look like a command failure. Decouple sandbox diagnostics from r.stderr so callers can attribute the two streams independently: - WarningsWriter(io.Writer) routes the buffered warnings to a dedicated sink. Defaults to r.stderr when unset, preserving today's behaviour byte-for-byte for callers that don't opt in. - Runner.Warnings() returns the warnings as []string for integrators that prefer to render them in their own structured output rather than scraping a writer. Closes the rshell side of #191. The PAR (datadog-agent) and remote-action UI (dd-source) changes will land separately and consume this API. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
AlexandreYang
approved these changes
Apr 27, 2026
gh-worker-dd-mergequeue-cf854d Bot
pushed a commit
to DataDog/datadog-agent
that referenced
this pull request
Apr 27, 2026
### What does this PR do? - Bumps `github.com/DataDog/rshell` from `v0.0.13` to `v0.0.14`. No call-site changes. ### Motivation - v0.0.13..v0.0.14 contains a single commit, [DataDog/rshell#200](DataDog/rshell#200), which adds an opt-in `interp.WarningsWriter(io.Writer)` option and a `Runner.Warnings() []string` accessor. Today's PAR rshell handler does not pass either, so behaviour is byte-for-byte unchanged: sandbox warnings continue to fall back to `r.stderr`, which is where the handler already routes them. - This bump lands in isolation so the follow-up PR — wiring the new accessor into `RunCommandOutputs.SandboxWarnings` to fix [DataDog/rshell#191](DataDog/rshell#191) — is a clean, reviewable diff with no `go.mod`/`go.sum` noise. ### Describe how you validated your changes - `go get github.com/DataDog/rshell@v0.0.14` — single-line `go.mod` change, expected `go.sum` update. - `go build ./pkg/privateactionrunner/...` — clean. - `go test -count=1 ./pkg/privateactionrunner/bundles/remoteaction/rshell/...` — all tests pass. ### Additional Notes - Follow-up PR (forthcoming) will wire `runner.Warnings()` into the PAR rshell handler's response. The corresponding contract change in dd-source (additive `sandboxWarnings?: string[]` field on `RunCommandOutputs`) is open at [DataDog/dd-source#423305](DataDog/dd-source#423305). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: matthew.deguzman <matthew.deguzman@datadoghq.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What does this PR do?
Decouples
AllowedPathssandbox diagnostics fromr.stderrso library callers can attribute the two streams independently.interp.WarningsWriter(io.Writer) RunnerOption— routes buffered sandbox warnings to a dedicated sink. Rejectsnil. Defaults tor.stderrwhen unset, preserving today's behaviour byte-for-byte.(*interp.Runner).Warnings() []stringaccessor — returns sandbox warnings programmatically (one entry per warning,nilwhen none) so integrators can render them in their own structured output instead of scraping a writer.interp.New()now writes tor.warningsWriterand no longer nils the underlying buffer, so the accessor remains usable after construction.Motivation
Closes the rshell side of #191. When
AllowedPathscontains a directory that cannot be opened on the current host (e.g./var/logon Windows,C:\var\logon Linux),allowedpaths.Newrecords a diagnostic that gets flushed tor.stderrduringRunnerconstruction. For library callers like PAR that surfacer.stderrin structured output, this means every script execution in the session ends up with a non-empty stderr — making the result look like a command failure even thoughexitCodeis0.Reasoning behind the chosen shape:
r.stderr) rather than process stderr orio.Discard, because rshell is overwhelmingly used as a library — every real caller already wires upr.stderrfor command output, and silently dropping warnings on un-migrated callers would hide misconfiguration.This is the first of three coordinated PRs:
sandbox_warningsfield on the PAR response schema; UI hides the section when empty.Testing
go test ./...clean. New tests ininterp/allowed_paths_test.go:TestSandboxWarningsDefaultGoToStderr— regression check that the default sink isr.stderrand that warnings never land on stdout.TestSandboxWarningsRoutedToDedicatedWriter— verifies theWarningsWriterwriter receives the warnings andr.stderrstays clean.TestSandboxWarningsAccessor— three subtests covering the slice shape, the empty case, and that the accessor still works when the streaming flush is suppressed viaio.Discard.TestWarningsWriterRejectsNil—WarningsWriter(nil)returns an error.make fmtclean.go vet ./...clean. Symbol-allowlist analyzer (analysispackage) re-runs clean — initial draft usedstrings.TrimRightwhich is not on the interp allowlist, rewritten to usestrings.HasSuffix+ slice instead.Checklist
README.mdpointing callers at the new option/accessor🤖 Generated with Claude Code