GitHub Issue

claude CLI agent lane fails: ProviderInvocationError "confined body refused (rc=1)" with empty envelope (claude CLI 2.1.201)

Discovered On Jul 5, 2026
Primary Metric open
## Summary The `claude` agent lane from the quickstart (`shepherd demo write claude-readme`) fails immediately with `ProviderInvocationError: confined body refused (rc=1)` and an **empty result envelope** (no model iterations, empty `modelUsage`), even though `shepherd doctor claude` reports every check green. The model is never actually called. The offline/deterministic lane works perfectly on the same host. ## Environment - macOS (Darwin 27.0.0, Apple Silicon) - Python 3.13.13 - `shepherd-ai` 0.2.0 (pip, fresh venv) - `claude` CLI **2.1.201** (Claude Code), signed-in via OAuth (Claude subscription), on `PATH` as an alias `claude=claude-oauth` - `shepherd doctor claude` → all green, incl. `native-jail: available` and `claude-auth: signed-in 'claude' CLI (login is seeded into jailed runs)` ## Repro ```bash python -m venv .venv && . .venv/bin/activate pip install shepherd-ai mkdir ws && cd ws shepherd init shepherd doctor claude # all green # seed a small README.md and commit it, then: shepherd demo write claude-readme > agent_task.py python agent_task.py # fails ``` ## Observed ``` RunStartError: run run-XXXX failed: ProviderInvocationError: confined body refused (rc=1): ..."service_tier":"standard","cache_creation":{...},"inference_geo":"", "iterations":[],..."modelUsage":{},"permission_denials":[], "terminal_reason":"completed","fast_mode_state":"off","uuid":"..."} ``` - `shepherd run show ` → `status: failed`, `enforcement: jail (laun...
View Raw Thread

Developer & User Discourse

dcx • Jul 5, 2026
Thanks for the detailed writeup! That is odd – this should work, I've been using the CLI lane internally. Investigating now.
dcx • Jul 5, 2026
Update: Your repro does work fine on my machine (*as in, it's not failing)! I'm continuing to investigate, but have run into an unrelated logging issue. I think this workaround may get you up and running in the meantime:

1. Run `claude setup-token` to get an OAuth token.
2. Make this available via `export CLAUDE_CODE_OAUTH_TOKEN=…`
3. Proceed with `python agent_task.py`, etc.

I hope that works! I'll be back to get to the bottom of this in a couple of hours either way – have an IRL commitment.
giorgosn • Jul 6, 2026
**Datapoint: the CLI lane works on Linux at 0.2.0 with `claude` 2.1.201.**

Just ran the exact repro on WSL2 Ubuntu 24.04 (Landlock jail), Python 3.12, `shepherd-ai` 0.2.0 (fresh venv), `claude` CLI 2.1.201 signed in via OAuth (subscription, no env keys):

```
shepherd demo write claude-readme > agent_task.py
python agent_task.py # → run retained, README.md edited
```

`run show --json` → `status: retained`, `enforcement: syscall_jail / confined_process`, changeset holds the README edit. So this doesn't look like global CLI-contract drift at 2.1.201 — the divergence is somewhere in the macOS/auth path.

**Why the envelope looks empty (and where the real error is).** The refusal message is built as `(stderr+stdout)[-300:]` (`shepherd_dialect/providers.py`, `ClaudeHeadlessProvider`). When the headless CLI fails, it emits a JSON *result envelope* with the human-readable error in the `result` field — which sits near the **front** of the JSON. The last 300 chars are just the `usage…termin...