# Troubleshooting

Source: https://flow-next.dev/reference/troubleshooting/

Common recovery patterns - post-update drift, stuck tasks, Ralph debugging, review-loop caps, model downgrades, Windows Python discovery, and clean uninstall.

Common recovery patterns for stuck tasks, broken state, Ralph debugging, and review-backend conflicts. For deeper subsystem guides see the [flowctl CLI reference](https://flow-next.dev/flowctl/cli-reference/), [Ralph internals](https://flow-next.dev/autonomy/ralph/), and the [source repository](https://github.com/gmickel/flow-next).

## Updated the plugin: do I re-run setup?

**No.** Setup copies nothing into your repo, so a plugin update (`/plugin` update, `droid plugin update`, or `git pull` + re-install on Codex/Cursor) is the whole update: every skill resolves `flowctl` from the plugin install itself, and the agent guide comes from `flowctl usage`. Re-run `/flow-next:setup` only when setup tells you the docs-snippet schema bumped, or when you want to change configuration or re-seed the user-owned files. It stays idempotent and non-destructive - your specs, tasks, memory, and config are untouched.

## I have `.flow/bin/` from an old install

Delete it. `.flow/bin/`, `.flow/templates/spec.md`, and `.flow/usage.md` are snapshots from the retired copy layout; nothing reads them, and removing them changes nothing observable in any workflow. One exception before you bulk-delete: a `.flow/templates/spec.md` you EDITED is your content - copy it to a repo-root `SPEC.md` first (that is the customization point now); setup’s cleanup offer detects a differing template and never deletes it for you. Keeping leftovers is a hazard, not a safety net - a stale copied `flowctl` can shadow the current one, and a `flowctl` flag that “should exist” erroring is the classic symptom. `/flow-next:setup` detects the leftovers and offers to delete them (`/flow-next:plan` prints a one-line nudge and moves on); you can also remove them yourself (use `git rm` for tracked copies).

## Two specs share the same number (`fn-122` twice)

**Symptoms:** `flowctl validate --all` reports a duplicate ordinal, or bare `fn-122` refuses to resolve and lists two candidates.

**What it means:** two full ids like `fn-122-foo-bar` and `fn-122-other-slug` exist. The **full id is the identity** (filesystem path, branch, task ids). A shared ordinal is **untidy, not broken** - validate treats it as a **warning**, not a root error.

**What to do:**

1. **Do not renumber.** Ids never change. They already live in commits, branches, tags, PR bodies, tracker comments, and memory entries you cannot rewrite safely.
2. Prefer the **full slug** when the bare form is ambiguous. The resolver lists candidates and requires the full id (same idea as git short-hash disambiguation).
3. **Avoid it next time.** With a tracker configured, set the team default so new specs mint from the issue key instead of racing on `fn-N`:

```bash
flowctl config set tracker.specIds tracker
```

Native allocation is also wider than it used to be - it scans every registered worktree and every ref, not only the local working tree - which closes most same-repo parallel creates. Separate clones that have not fetched each other can still collide; that is what tracker-keyed ids are for. Details: [Collaboration](https://flow-next.dev/guides/for-teams/#spec-ids-when-several-people-create-work), [Tracker Sync](https://flow-next.dev/integrations/tracker-sync/#duplicate-ordinals).

## Reset a stuck task

```bash
# Check task status
flowctl show fn-1.2 --json


# Reset to todo (from done/blocked)
flowctl task reset fn-1.2


# Reset + dependents in same spec
flowctl task reset fn-1.2 --cascade
```

`--cascade` walks the spec’s `depends_on` graph and resets every downstream task that referenced the target, so the next `flowctl ready` call surfaces them again.

## Clean up `.flow/` safely

Run manually in terminal (not via AI agent - destructive command guards block agents from running `rm -rf`):

```bash
# Remove all flow state (keeps git history)
rm -rf .flow/


# Re-initialize
flowctl init
```

Or run `/flow-next:uninstall` to clean up docs and get the commands printed for manual execution.

## Debug Ralph runs

```bash
# Check run progress
cat scripts/ralph/runs/*/progress.txt


# View iteration logs
ls scripts/ralph/runs/*/iter-*.log


# Check for blocked tasks
ls scripts/ralph/runs/*/block-*.md
```

Each Ralph run lives under `scripts/ralph/runs/<timestamp>/`. The directory contains the iteration log, receipts (review / walkthrough / blocked), and an optional `progress.txt` tail. Deep dive: [Ralph internals](https://flow-next.dev/autonomy/ralph/).

## Receipt validation failing

```bash
# Check receipt exists
ls scripts/ralph/runs/*/receipts/


# Verify receipt format
cat scripts/ralph/runs/*/receipts/impl-fn-1.1.json
# Must have: {"type":"impl_review","id":"fn-1.1",...}
```

Ralph reads receipts to decide whether to advance, retry, or block. A missing or malformed receipt freezes the loop. The bundled `flowctl validate --all` checks state-file shape; receipt-shape errors usually mean a backend wrote the file mid-iteration and the loop crashed.

## Review loop stalls, repeats unchanged work, or runs away

**Symptoms:** a plan/impl/completion review loops far more than the round cap - the field report was **\~11x** on a large ticket before the reviewer and implementer converged. Most common on the **Cursor** review backend, but the underlying causes were backend-agnostic.

**What was happening (root causes, now bounded):**

* **The cap was prose-only and reset every invocation.** `MAX_REVIEW_ITERATIONS` (then default 4; now 8) was an instruction to the host LLM to keep an in-context counter - but it reset to 0 on every *fresh* review invocation (a new Ralph iteration, a new pilot tick, a human retry). The runaway was about 5-6 fresh invocations x \~3 in-agent rounds. Now flowctl owns a **cumulative counter on spec state** that survives fresh invocations and **refuses at the cap** (exit `4` + `ESCALATE:`).
* **Every re-review was a fresh blind review** (a churn lottery - two identical fresh Cursor reviews overlapped on only \~50% of findings, so SHIP was statistically near-unreachable within the cap). The **convergence ratchet** now renders the validated structured findings (severity, classification, status) with labeled legacy prose only as fallback. Its shrink-only contract remains: verify each prior finding fixed; only a NEW >= Major finding may block; all prior fixed + no new >= Major means MUST SHIP.
* **Codex/copilot verdicts could be poisoned** by a verdict literal echoed in tool output (e.g. a grep of `smoke_test.sh`’s assertions), making flowctl report SHIP while the reviewer said NEEDS\_WORK - a false SHIP *or* a false NEEDS\_WORK that kept a loop alive. The parse now isolates the final agent message (last-match).
* **Cursor’s ambient injection** (its built-in persona rubric + auto-attached `AGENTS.md`) diluted the scope anchor. A **persona-override preamble** now rides in every cursor review prompt (see [Orchestration](https://flow-next.dev/guides/model-routing/)).

**What the loop can do on its own now:** the cap reads the structured findings each verdict persists and ends a measurably stuck loop early - exit `4` with `ESCALATE: review loop stalled (<rule>)` - and a reviewer can return `NEEDS_HUMAN` when the next step is a judgment call, which persists its receipt and status before exiting `4` with `ESCALATE: reviewer requested human review`. Re-dispatching an unchanged artifact is refused before it costs a round (`NOT_RETRYABLE: artifact unchanged since last verdict`, exit `1`).

**What to do when it escalates:**

* `NOT_RETRYABLE` (exit `1`) consumed nothing. Change the actual reviewed artifact, or decide as a human whether an explicit re-plan is warranted - do not blindly retry.
* Either `ESCALATE:` variant (exit `4`) is **NOT retryable**. Under Ralph/autonomous it surfaces as NEEDS\_HUMAN. Inspect the persisted receipt and findings trail, then decide: redesign, focused fix, or re-plan (the reviewer strictness is often *signal* - big/ambiguous plans really do re-fail).
* After an explicit **re-plan** (you rewrote the spec/approach, not just patched a finding), a human can reset the counter to re-open the cap: `flowctl spec reset-review-rounds <spec-id>` (add `--impl` to also clear per-task impl-review counters). A `SHIP` verdict resets automatically. Ralph blocks reset commands and `--force` - they are human-only recovery tools, never autonomous ones.
* The default cap is 8. Tune `MAX_REVIEW_ITERATIONS` (env / Ralph `config.env`) for a genuinely large ticket, but the cap stays enabled and escalation stays preferable to a larger budget.
* Full semantics: [flowctl CLI reference](https://flow-next.dev/flowctl/cli-reference/) and [Ralph review loops](https://flow-next.dev/autonomy/ralph/).

## Review reports a model downgrade or floor

**Symptom:** a review prints one stderr line like

```text
warning: codex model '<ranking-top id>' unavailable; downgraded to '<available id>'. Cached for this CLI version.
```

(or `... fell back to the never-fail floor (the CLI default / 'auto')`), and the review’s receipt records the downgraded id / `auto` / `default` rather than the ranking top.

**This is expected, not an error.** Flow-Next dispatches the *strongest* model by default and, when the local CLI can’t run it, transparently resolves the best available one (the model-resolution ladder). It fires ONLY on the distinctive model-unavailable signature (codex *“requires a newer version of Codex”*, copilot *`... from --model flag is not available`*, cursor *`Cannot use this model: ...`*, claude an exit-0 error payload whose text names the selected model, or the `[claude-code:unrecognized_model]` stderr tag); auth / network / sandbox / timeout failures propagate unchanged.

**What to do:**

* **Want the top model?** Upgrade the backend CLI. The cache key is `(backend, CLI version)`, so the upgrade re-resolves automatically on the next review.
* **The downgrade repeats every review?** It shouldn’t - the result is memoized in `.flow/.cache/model-resolution.json`. If it does, that file may be unwritable (check permissions) or you’re on a fresh CLI version each run.
* **Force a specific model** (skip the ladder + cache entirely): pin it explicitly - `--spec codex:<model-id>`, a per-task/per-spec `review:` value, `FLOW_CODEX_MODEL`, or `review.backend`. An explicit unavailable model errors clearly instead of downgrading.
* **Reset the cache:** `rm -rf .flow/.cache/` - it is regenerated (and gitignored) on the next review; a corrupt file is already treated as a cold start.

## Custom RepoPrompt CLI instructions conflicting

If you have custom RepoPrompt CLI instructions in your `CLAUDE.md` or `AGENTS.md`, they may conflict with Flow-Next’s integration.

Flow-Next’s plan-review and impl-review skills include specific instructions for CE-first CLI discovery, window selection, builder workflow, and chat commands. Custom instructions can override these and cause unexpected behavior.

**Symptoms:**

* Reviews not using the correct RepoPrompt window
* Builder not selecting expected files
* Chat commands failing or behaving differently

**Fix:** Remove or comment out custom RepoPrompt CLI instructions from your `CLAUDE.md`/`AGENTS.md` when using Flow-Next reviews. The plugin provides the complete CE-first workflow.

RepoPrompt is macOS-only. When the CE-first ladder (`rpce-cli`, the two CE user links, then discontinued Classic `rp-cli`) finds no runnable candidate, `/flow-next:plan` and the review skills do not propose RepoPrompt. Explicit `--review=rp` remains accepted and errors at runtime when no supported RepoPrompt CLI is available. Once CE is selected, connection or command failures do not retry against Classic.

## Windows: `python3` not found / Microsoft Store alias stub

Windows note for 4.0.0: the copy-less resolution chain is **untested live on Windows - best-effort**. `flowctl` (Git Bash / WSL) and the `flowctl.cmd` sibling (cmd.exe / PowerShell) ship side by side in the plugin’s `scripts/` directory. Report breakage.

**Symptom:** on Windows, `flowctl` fails with *“Python was not found; run without arguments to install from the Microsoft Store…”* and exit code **9009**, even though you installed real Python.

**Cause:** `python3` resolves to the Microsoft Store **App Execution Alias** - a 0-byte reparse point at `%LOCALAPPDATA%\Microsoft\WindowsApps\python3.exe` that Windows ships **enabled by default**. When your real Python came from [python.org](https://python.org/) or the `py` launcher (not the Store), the stub shadows it: it satisfies `command -v python3` (it *is* on `PATH`) but is non-functional. Older flowctl launchers trusted presence over function and picked the stub - so flow-next broke on every Windows machine in this configuration.

**The shipped fix (no action needed on a fresh install):** the `flowctl` launchers now **probe interpreter functionality** - each candidate must actually run `<cand> -c "import sys"` and exit 0 - in order `$PYTHON_BIN` then `py -3` then `python3` then `python`, so the 9009 stub is skipped. A `flowctl.cmd` batch shim ships alongside the extensionless bash `flowctl`, so PowerShell / cmd.exe (Claude Desktop, native Codex, native Cursor) resolve a working interpreter too.

**Recovering a legacy copied install** (a pre-fix `.flow/bin/flowctl` hardcodes `exec python3` and cannot fix itself). This only applies to repos still carrying the retired copy layout. Pick either:

1. **Delete the copy (recommended, durable).** The plugin’s own launchers already carry the fix, and nothing reads `.flow/bin/` any more:

   ```powershell
   Remove-Item -Recurse -Force .flow\bin        # git rm -rq .flow/bin if it is tracked
   ```

   After this, `flowctl` (Git Bash / WSL) and the `flowctl.cmd` sibling (cmd.exe / PowerShell) resolve from the plugin install. The copy-less chain is untested live on Windows - best-effort; report breakage. `/flow-next:setup` offers the same deletion interactively.

2. **Disable the Store alias (per-machine OS workaround).** Settings, then Apps, then Advanced app settings, then **App execution aliases**: toggle **OFF** for `python.exe` **and** `python3.exe`. `python3` then resolves to your real install. Note the `py` launcher is [not included with Store Python](https://learn.microsoft.com/windows/python/faqs), so if you were relying on Store Python, install python.org Python (which ships `py`) to get `py -3`.

Prefer path 1 - the alias toggle is per-machine, not durable, and does not survive a fresh Windows profile.

**Sources:** Microsoft Learn [Python on Windows FAQ](https://learn.microsoft.com/windows/python/faqs) (the App Execution Alias stub + “the py launcher is not included with Store Python” + disabling the alias); python.org [Using Python on Windows](https://docs.python.org/3/using/windows.html) and [PEP 397](https://peps.python.org/pep-0397/) (the `py` launcher / `py -3`).

## `/flow-next:map`: clawpatch not found / version mismatch / Node 20

[`/flow-next:map`](https://flow-next.dev/skills/map/) wraps the upstream `clawpatch` CLI. Common failure modes:

**1. `clawpatch` binary missing.** Skill prints `pnpm add -g clawpatch` install instructions verbatim and exits 1. No auto-install - global npm/pnpm installs are user-consent territory.

```bash
# Recommended: install globally with pnpm
pnpm add -g clawpatch
```

**2. pnpm installed `clawpatch` but it’s not on PATH.** pnpm installs global binaries under `$PNPM_HOME` and needs a one-time `pnpm setup` to wire PATH - without it, the install lands but the binary isn’t resolvable. (Exact location varies by pnpm version and OS: `~/.local/share/pnpm` on many setups, `$PNPM_HOME/bin/` on others - `pnpm bin -g` reports yours.) Skill detects `pnpm bin -g` exit-0 + `command -v clawpatch` exit non-zero and prints the PNPM\_HOME hint:

```bash
pnpm setup            # writes PNPM_HOME + adds it to your shell rc
source ~/.zshrc       # or ~/.bashrc - pick up the new PATH entry
command -v clawpatch  # should now resolve
```

**3. `clawpatch --version` falls outside the tested range.** The skill carries a single-source `SUPPORTED_CLAWPATCH` version range in its prose. Outside range emits a one-line stderr warning naming expected vs found and continues (degrades - never blocks). Re-pin lands on each clawpatch minor.

**4. Node 20 with `clawpatch` installed.** clawpatch’s `engines.node: ">=22"` triggers its own error; the skill propagates it verbatim. Upgrade Node 22+ (e.g. `nvm install 22 && nvm use 22`) or skip `/flow-next:map` - scouts gracefully fall back to the grep/glob path when `.clawpatch/` is absent.

**5. “Should I commit `.clawpatch/` to the repo?”** No - by default the skill writes a `.clawpatch/.gitignore` with `*` + `!.gitignore`, making the feature index local-per-developer. The map is regenerable from `clawpatch map`, the schema may flip between pre-1.0 minor releases, and committing it creates PR review noise + merge conflicts. The full trade-off table is on the [Map skill page](https://flow-next.dev/skills/map/). Teams that want shared indexes can customize the skeleton - unsupported, but the skill won’t clobber a customized `.gitignore` on re-run.

The skill is **opt-in convenience** - `flowctl` core never imports or requires clawpatch; nothing else in flow-next breaks when the skill can’t run.

## Uninstall

Run manually in terminal (DCG blocks these from AI agents):

```bash
rm -rf .flow/               # Core flow state
rm -rf scripts/ralph/       # Ralph (if enabled)
```

Or use `/flow-next:uninstall` which cleans up docs and prints commands to run. Doc cleanup removes two independent marker blocks from `CLAUDE.md`/`AGENTS.md`: the `<!-- BEGIN FLOW-NEXT -->` … `<!-- END FLOW-NEXT -->` instructions block and, if `/flow-next:setup` scaffolded one, the `<!-- flow-next:model-routing:start -->` … `<!-- flow-next:model-routing:end -->` model-routing block (removed only when its marker pair is well-formed - a damaged pair is reported and left untouched). `GLOSSARY.md` and `STRATEGY.md` at the repo root are intentionally preserved - they outlive flow-next per the survives-uninstall invariant.

## Cursor in-IDE browser MCP missing (`cursor-ide-browser`)

On Cursor, drive / QA probes the built-in browser by MCP id `cursor-ide-browser`. A catalog miss is not absence.

1. Settings → Tools & MCP → **Browser Automation** = Browser Tab.
2. Type `@Browser` in chat (no space), or open the Browser pane until it shows connected.
3. Let the agent re-probe once. Do not loop.

A mid-run `MCP server does not exist: cursor-ide-browser` after the pane was already driving is a known Cursor flake. `@Browser` does not restore that session - quit Cursor fully, wait \~10s, confirm the pane is connected, start a fresh chat. See [Flow-Next Drive](https://flow-next.dev/skills/flow-next-drive/) and [Install → Cursor](https://flow-next.dev/install/#cursor).

## A stale skill name survives an upgrade

A cached install can keep surfacing a skill under its old name after a rename (`browser` became `flow-next-drive` in 1.4.0). It auto-clears within about seven days as the plugin cache refreshes. To clear it immediately, delete the stale cached marketplace directory under your host’s plugin cache path and reload the host.

```bash
rm -rf ~/.claude/plugins/cache/<marketplace>   # then reload Claude Code
```

## See also

* [flowctl CLI reference](https://flow-next.dev/flowctl/cli-reference/) - every command, flag, default
* [Ralph](https://flow-next.dev/autonomy/ralph/) - loop internals + DCG setup
* [Platform notes](https://github.com/gmickel/flow-next/blob/main/plugins/flow-next/docs/platforms.md) - platform-specific gotchas (Droid, Codex, Cursor, OpenCode)
* [Glossary](https://flow-next.dev/reference/glossary/) - the canonical vocabulary
