microsoft / microsoft/vscode

SDK shell misses local sandbox retry when a pipeline masks the denied command's exit code

Open
#333,898 1 comment 0 reactions 1 assignee Claimed by @dileepyavan View on GitHub
Dominant language
TypeScript
Stars
193k
Forks
42.4k
PR merge metrics
PR metrics pending

Description

## Summary

A sandboxed SDK shell command can be denied even though the overall command reports exit code 0. In the captured VS Code session, the denial was returned to the model as a successful tool result instead of triggering the local confirmation-backed retry.

The same command was tested twice in the standalone CLI on September 1, 2026. Both times, the CLI detected the hidden denial and presented an outside-sandbox approval before completing the original tool call.

## Reproduction

1. Enable the agent sandbox and allow individual commands to run outside it after confirmation.
2. Open a workspace whose sandbox policy does not allow reading the home directory.
3. Ask the agent to list the immediate directories in the home folder.
4. Let it run:

```bash
find "$HOME" -mindepth 1 -maxdepth 1 -type d -print | sort
```

## VS Code result

The captured AHP and session logs show:

- The permission request had `kind: "shell"`. This was the SDK built-in shell, not an Agent Host custom tool.
- The original call did not request sandbox bypass.
- The execution had `sandboxApplied: "true"` and `sandboxOptOutRequested: "false"`.
- `find` printed an `Operation not permitted` error for the home directory.
- The trailing `sort` succeeded, so the pipeline completed with exit code 0.
- The tool completion was marked successful and returned to the model.
- No local outside-sandbox approval was presented.

The logs also contain inconsistent path evidence:

- `tool.execution_start.shellToolInfo.possiblePaths` included the resolved home path.
- The subsequent shell permission request had an empty `possiblePaths` array.

That missing path evidence may prevent an ambiguous `Operation not permitted` message from being correlated with the active filesystem policy.

## Standalone CLI control

The exact command was run twice from the same workspace in the standalone CLI with sandboxing enabled.

On both attempts:

1. The agent submitted a normal sandboxed shell call without `requestSandboxBypass`.
2. The internal sandboxed execution was denied.
3. The successful `sort` stage still left the pipeline with exit code 0.
4. Before returning any tool result to the agent, the CLI presented an approval to rerun the same command outside the sandbox.
5. Rejecting the approval completed the tool call as rejected. No home-directory contents were returned.

The first sandbox denial was never returned to the model. The local retry offer was generated after the initial attempt failed, not requested preemptively by the agent.

## Two distinct recovery paths

There are two different behaviors that should not be conflated:

1. **Local retry offer.** The host/runtime detects the sandbox denial before completing the original tool call. It asks the user whether to rerun the same operation outside the sandbox. If approved, the rerun completes the original tool call without another model inference.
2. **Model-facing failure guidance.** A completed denial is returned to the model with instructions to submit another tool call requesting bypass. This costs another model turn and depends on the model interpreting the failure correctly.

This issue concerns the first behavior. Adding instructions to the returned failure would be a fallback, not a complete fix.

## What the control establishes

The standalone CLI behavior demonstrates that local retry detection can handle a pipeline whose final exit code masks an earlier denied step.

For a zero-exit pipeline, output text alone should not trigger an elevation prompt. A command could merely print words such as `Operation not permitted`. The denial should be corroborated using the active sandbox policy and the command's extracted paths or other reliable sandbox evidence.

This places the likely gap in the SDK/runtime version or metadata integration used by the VS Code session, rather than in model behavior or the Agent Host custom terminal tool.

## Expected behavior

When a sandboxed pipeline contains a denied operation, VS Code should:

1. Detect recognized sandbox-denial evidence even when a later pipeline stage produces exit code 0.
2. Correlate ambiguous output with the command's extracted paths and active sandbox policy.
3. Present an approval to rerun the same command outside the sandbox when bypass is enabled.
4. If approved, rerun locally and return the final result under the original tool call without another model inference.
5. If declined, keep the operation sandboxed and return the rejection normally.
6. Offer the local retry at most once.

The path metadata used during execution, permission handling, and denial detection should remain consistent.

## Approval prompt attribution

The approval UI should explain that the agent submitted a normal sandboxed call, the first execution was blocked, and VS Code is now offering to rerun that same command outside the sandbox.

A generic outside-sandbox approval can otherwise make it appear that the agent requested elevated access before trying the sandboxed operation.

_🤖 Posted by GitHub Copilot on Harald's behalf._

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.