tasks
Guides

Troubleshooting

Reading validate findings, and what each common failure actually means.

Start here, always

Run tasks validate before hand-repairing anything. It reports id/filename mismatches, phase drift, unknown statuses, broken or cyclic dependencies, and a stale _index.md — and --fix repairs the mechanically safe subset.

tasks validate --fix

Errors exit 4, so CI can gate on them. Warnings do not.

Common failures

Reading validate findings

KindSeverity--fixWhat happened
filename-mismatcherroryesThe file is named x.md but declares id: y. Fix renames the file to match the id.
phase-drifterroryesFrontmatter's phase disagrees with the containing directory. The directory wins; fix rewrites the field.
stale-indexwarningyes_index.md no longer matches the tasks on disk. Fix regenerates it.
malformederrornoThe file could not be parsed as a task at all.
duplicate-iderrornoTwo live files declare the same id.
unknown-statuserrornoA status not in the configured list.
malformed-referrornoA depends_on entry that will not parse.
cycleerrornoA dependency cycle.
dependency-missing / dependency-archived / dependency-unresolved-projectwarningnoA dependency that will never be satisfied, so the task can never become ready.

--fix applies only the mechanically safe repairs and reports the rest for a human. Exit 0 with {"ok": true, "findings": []} means the tree is clean.

Fixing the ones --fix cannot

duplicate-id — usually a bad merge, or a mv that should have been tasks move. Decide which file is real, delete or re-id the other, then re-run validate.

malformed — open the file. It is almost always a YAML error in the frontmatter: an unquoted timestamp, a stray tab, an unclosed ---. Compare against the file format.

unknown-status — a status was renamed in config.yml without migrating the tasks. See migrating an existing tree.

cycle — break it with tasks dep rm. This is worth fixing promptly: a cycle silently drops every task in it out of tasks ready forever, which is the worst failure mode for an agent that trusts the query.

dependency-* — the reference points at something that will never be done. Either recreate the missing task, or drop the edge:

tasks dep rm wire-refresh token-schema

Recovering from a bad state

A crashed tasks move. The move writes the destination before unlinking the source, so a crash leaves a duplicate rather than losing the task. tasks validate reports it as duplicate-id; delete whichever copy is in the wrong place.

A stale lock. Locks live in .tasks/.locks/ and go stale after 10 seconds, so a crashed process does not block claims for long. If one somehow persists, deleting the file is safe — .locks/ is git-ignored and holds no state.

Anything else. .tasks/ is committed, so the ordinary answer applies:

git diff .tasks
git checkout -- .tasks

That is the real reason task state lives in the repo: recovery is the same recovery you already know.

On this page