# Troubleshooting

`/ultra-config doctor` reports profile, model catalogue, pin versions, and budget status.

- `Auto mode requires a saved budget`: run `/ultra-config budget <weekly> [daily]` or explicitly acknowledge one task.
- `Profile config mismatch`: start the matching `pi-private` or `pi-free` launcher; do not copy auth files between them.
- `Guarded execution asks/blocks`: use a simple allowlisted argv command (`npm test`, `npm run lint`, `git diff`, `rg`, `node --test`), without shell operators.
- `Provider cooldown`: wait for the recorded cooldown; UltraPi halves concurrency on 429 responses and does not retry in a storm.
- `Workflow unavailable`: verify `npm run verify`, then reload Pi. The implementation pins Pi `0.84.1` and `pi-agents` `0.13.2`.

Do not treat Pi project trust or extension permissions as an OS sandbox. Run unattended writers in a container or VM when that isolation matters.

## When a run stops instead of answering

UltraPi ends a run in `BLOCKED`, `FAILED`, `CANCELLED`, or `BUDGET_EXHAUSTED` rather than hand back a result it could not verify. Every one of those endings names a blocker and the concrete next action, both in the answer the root agent presents and in the run's `result.completed` event:

```
UltraPi controller: BLOCKED · completed=none recorded · verified=no · blocker=acceptance-command-required · est. $0.02 · run=<id>
What is required to continue: Rerun with an executable acceptance check, for example: /ultra <task>. Acceptance: npm test
```

The blocker is a stable code you can grep for in telemetry; the next action is written for a person. If you ever see an ending without one, that is a bug — the field is filled for every non-success state, including reasons added by future code paths, which fall back to a per-state instruction.
