Skip to content

Troubleshooting ​

First-run problems, then the edge cases of a solo, hook-free, pointer-free pipeline where enforcement is convention, not a gate.

First run ​

/task: commands don't appear after installing ​

Symptom — typing /task: shows nothing; no /task:to-task, /task:to-plan, etc.

Cause — the task plugin isn't installed/enabled in this session, or the marketplace was never added.

Fix

text
/plugin marketplace add https://github.com/SpaiR/task-pipeline.git
/plugin install task@task-pipeline

Then reopen the / menu. If it was already installed, make sure it isn't disabled (/plugin).

The code-reviewer agent doesn't resolve ​

Symptom — the session implements and commits, then reports that the agent type task:code-reviewer doesn't exist (or silently stops after the commit, with no review section in its output).

Cause — the review pass is the plugin's own agent (agents/code-reviewer.md), and the task file's ## Execution pointer sends the session to .task/CLAUDE.md → ## Executing a task, which names it directly, with no fallback. So it resolves only when the task plugin is installed and enabled in the session doing the work. The usual causes: the plugin is disabled, it was never installed in this project, the task file was written by a much older plugin version, or the agent was renamed in a local fork.

Fix — check /plugin and enable task; reinstall via the marketplace if it isn't listed. Also check that .task/CLAUDE.md → ## Executing a task still names task:code-reviewer (a hand-edit or an old setup can drop it). Then re-run implement .task/task/<slug>.md — the implementation is already committed, so the reviewer will simply review that commit and land any fixes as a second commit on top.

If you'd rather not run it at all, nothing is gated: the commit stands as it is, and you can run your project's build and tests plus your own review by hand. What you must not do is assume the review happened — a missing reviewer means no defect was proven and no fix was applied.

Why there's no fallback

Claude Code's own /verify and /code-review are marked disable-model-invocation, which means a subagent — and a session that was merely told implement … rather than typing the command itself — cannot run them, and the failure is silent: an unlisted command is skipped, not refused, so the run would still report success. The pipeline names its own agent instead, so a missing reviewer fails loudly.

The roadmap driver doesn't resolve ​

Symptom — /task:roadmap-to-workflow stops before the first item. Either it reports that task:roadmap-driver isn't registered, or — on an older plugin — it fails with scriptPath must be a script path this tool returned, or a file you can already read (the working directory or a directory you have added), naming a path inside the plugin.

Cause — autopilot runs a driver script the plugin ships, and the plugin has to register that script for the Workflow tool to accept it by name. Older versions instead passed the driver's absolute path, and the Workflow tool permission-checks a path against your session's working directory — a plugin never lives inside it, so the run died everywhere except a checkout of the plugin repository itself. Current versions declare the driver in the plugin manifest and call it by name, so an unresolved name means this session is holding a stale copy of the plugin, or the plugin was updated without a restart.

Fix — update or reinstall the task plugin, restart Claude Code, then rerun /task:roadmap-to-workflow <slug>. The stop costs you nothing: items already ticked stay ticked, and a rerun picks up only the unchecked remainder.

If you are stuck on an older plugin and can't update it, starting Claude Code with the plugin's own directory added — claude --add-dir <path to the plugin> — makes the old path-based call pass the permission check. That is a workaround for the old skill, not something the current one needs.

A skill aborts with a permission error before doing anything ​

Symptom — /task:to-task (or any capture skill, or /task:roadmap-to-workflow) stops immediately with a permission error naming a preflight.sh command, and nothing is written.

Cause — each of those skills opens by having Claude Code run the plugin's own preflight.sh and substitute its output into the skill text, so the resolved .task/ root, whether the project is set up, and the existing roadmaps/tasks/specs all arrive without a single tool call. Such an injected command never raises an approval prompt: if it matches no permission rule, the whole invocation aborts. The rule ships with the skill (allowed-tools in its frontmatter), so this only shows up when a local deny rule, an enterprise-managed setting, or a fork's edited frontmatter blocks it.

Fix — allow the plugin's own helpers in your settings, or drop the deny rule that covers them:

json
{
  "permissions": {
    "allow": ["Bash(bash *skills/_lib/preflight.sh* *)"]
  }
}

Nothing was written when this fires, so re-running the command after fixing the rule is safe.

"CLAUDE.md not found" ​

Symptom — a skill stops with .task/CLAUDE.md not found.

Cause — /task:roadmap-to-workflow and validate require .task/CLAUDE.md, and it hasn't been written in this project yet. The five intake-capable capture skills (to-task / to-plan / to-roadmap / to-architecture / to-spec) write it inline on first use instead of stopping, and /task:grill needs no setup at all. There is no separate setup command — setup is folded inline into those five capture skills.

Fix — run any of /task:to-task, /task:to-plan, /task:to-roadmap, /task:to-architecture, or /task:to-spec. Each detects language and test policy, writes .task/CLAUDE.md, records git config task.root, reports what it wrote, and continues into the capture. /task:roadmap-to-workflow is not setup-capable by design — if you hit this there, run a capture skill first, then retry.

.task/ shows up in git status ​

Symptom — .task/ appears as untracked in git status.

Cause — .task/.gitignore, the self-ignoring * that keeps the folder out of git, is missing — deleted by hand, or .task/ was created before setup ran.

Fix — run any /task: skill except grill; its entry check recreates a missing .task/.gitignore on a configured project. Or write it yourself: printf '*\n' > .task/.gitignore. The rule lives inside .task/ on purpose — the pipeline never touches a tracked file or .git/info/exclude, and the rule leaves with the folder.

Searching inside .task/ finds nothing ​

Symptom — a search scoped to .task/ comes back empty although the files are there: rg <pattern> .task, Claude Code's Grep with path .task, or your editor's search restricted to that folder.

Cause — ripgrep, which all three use, applies .task/.gitignore's * to the folder's own files. A search from the repo root skipping .task/ is expected; this is the same rule seen from inside.

Fix — list or open the files directly (ls .task/task, a Glob, or reading the path), or search with rg --no-ignore <pattern> .task. The pipeline itself is unaffected: its helpers enumerate files with shell globs, and every skill hands an explicit artifact path to the session that reads it.

validate.sh ends with "FAIL N error(s)" ​

Symptom — bash "${CLAUDE_PLUGIN_ROOT}/skills/validate/validate.sh" all ends with FAIL <N> error(s), preceded by ERROR <label>: <message> lines.

Cause — a task or roadmap file drifted from the expected format: a missing # <Title> first line, no --- separator, no ## Description, a ## Plan with zero ### Step N: blocks, a roadmap item missing its checkbox prefix or a required sub-heading, a roadmap item heading that nearly matches the required form ([X] uppercase, a double space around the checkbox, ####, or the checkbox deleted), a **Dependencies:** value that doesn't parse (use an em dash for none, or a comma-separated list of item numbers), one that cites a number with no matching item, one that lists its own item, or a file saved with CRLF line endings.

Fix — read each ERROR <label>: line (it names the file and the exact problem) and fix the artifact by hand — these are plain Markdown files. Re-check with validate.sh all. It's an optional self-check, not a gate — only genuine structural ERRORs are worth fixing before you hand the file to an implementing session; a WARN never blocks anything.

validate.sh warns "no such spec … (dangling reference)" ​

Symptom — a WARN names a Spec: header pointing at a .task/spec/<slug>.md that doesn't exist.

Cause — the header names a spec that was never written, was renamed, or was deleted. This is the pipeline's one cross-file check, and only ever a WARN.

Fix — capture the missing spec with /task:to-spec (using that slug), correct the slug in the header, or drop the header if the reference is stale. The check reads the slug from the header's link text, so Spec: [<slug>](../spec/<slug>.md) and a bare Spec: <slug> behave the same — a hand-edited header in either form is never flagged for its shape, only for a spec that genuinely isn't there.

Symptom — a WARN says a Spec: header's target isn't ../spec/<slug>.md.

Cause — the link text and the link target disagree, which is what renaming a spec and updating only one half leaves behind.

Fix — make the target ../spec/<slug>.md for the slug in the link text. Worth doing even though nothing is broken for the agent: every consumer resolves the label, so the task still implements correctly and only a human clicking the link lands on the wrong file — which is the one thing the link form was added to prevent.

Working with roadmaps ​

A roadmap item's checkbox never gets ticked ​

Cause — the auto-mark step is conditional on the task file carrying both Roadmap: and Source item: #N header lines, above the ---. If the file was hand-created, those headers were edited out, or the item number doesn't match, the executing session has nothing to key the flip off of.

Fix — check the top of .task/task/<item-slug>.md for both header lines and a correct #N. Add them if missing (ASCII, above ---, Roadmap: [<slug>](../roadmap/<slug>.md)) and re-run, or just tick the box yourself — it's a plain - [ ] → - [x] edit.

A roadmap-to-workflow run stops on a failed item ​

Cause — by design: the driver is stop-on-FAIL. A later wave never starts if an earlier item didn't land cleanly, since a later item may depend on it.

Fix — read the failure digest, fix the item (edit .task/task/<item-slug>.md, or re-implement it by hand), tick its checkbox, then rerun /task:roadmap-to-workflow <slug>. Completed items stay checked, so the rerun only picks up the unchecked remainder.

One digest is worth reading closely: a stop from the mark stage means the item's work already landed and was committed, and only the checkbox is behind. The flip is idempotent, so this is never "the box was already ticked" — it means the roadmap has no unique ### - [ ] N. heading for that item, because it was renumbered, retitled, or duplicated. Tick it by hand and rerun; there is nothing to re-implement.

A worktree can't find .task/ ​

Cause — worktrees resolve the shared .task/ through git config --local task.root (fallbacks: an upward walk, then dirname(git-common-dir), the main worktree root). That last fallback already covers every worktree of a repo whose .task/ sits at the main worktree root, anchor or not. A worktree gets lost when .task/ lives somewhere else — a subdirectory, as older versions allowed, or a spot you moved it to — and the anchor is missing or wrong. The anchor is written only by first-run setup; nothing records or repairs it on later runs.

A moved or copied repo leaves the anchor stale: task.root is an absolute path stored in .git/config, so it travels with the directory and keeps pointing at where the repo used to live. After a move that path is gone; after a copy it is the original repo, with its own .task/. The resolver trusts the anchor only when that path holds a .task/CLAUDE.md and belongs to the same git repository as the current checkout, so either kind of stale anchor is ignored, and the upward walk finds the checkout's own .task/. A copy never reads or writes the original's artifacts. The stale value stays in .git/config, ignored on every run, until you reset it.

Fix — set the anchor by hand: git config --local task.root /abs/path/containing/dot-task (the directory that contains .task, not .task itself). It lives in the repo-common config, so one command fixes every worktree. The path must belong to this repository (inside its working tree or one of its worktrees, or the directory that holds a bare repo); an anchor naming another repository is ignored. To clear a stale anchor left by a move or copy, run git config --local --unset task.root. Don't run a capture skill from the stuck worktree to fix it: that worktree resolves to a root with no .task/CLAUDE.md, so the skill's first-run setup writes a second .task/ there instead of finding yours.

Finding your own state ​

There is no active-task pointer to lose or heal — the artifact's path is the only handle.

text
ls .task/task/
# every task file you've captured; a task stays here until you delete it

grep -L '^## Plan' .task/task/*.md
# task files with a Description but no Plan yet (to-task-only captures)

grep '^### - \[ \]' .task/roadmap/<slug>.md
# every item still unchecked in that roadmap

Once you've found the file, any session picks it up with implement .task/task/<slug>.md.

→ See also the maintainer-facing artifact contract in the repo.

Released under the MIT License.