Troubleshooting
This guide covers common issues you may encounter with LumenFlow and how to resolve them.
Release reports an incoherent CLI artifact
Section titled “Release reports an incoherent CLI artifact”The release entry is required to use a dist artifact whose provenance sidecar matches the CLI source, dependency/lockfile, and build configuration digests, the current Node major/ABI, and the expected entry path. A source edit, dependency or build-config change, missing/corrupt sidecar, or Node ABI change therefore causes a locked rebuild; the old dist is never executed.
Follow the exact remediation printed by the launcher (normally:
pnpm install && pnpm build) and retry with Node 26. If the rebuild fails or
the sidecar remains mismatched, release stops before mutating versions, tags,
or registry state. Do not bypass this check with a timestamp assumption or a
force flag.
CLI build cache reports an unusable or unactivatable build
Section titled “CLI build cache reports an unusable or unactivatable build”Lifecycle commands that need a freshly built CLI resolve the build output by a
digest of its inputs and keep it in a per-machine cache outside every checkout
(~/.lumenflow/cache/cli-dist by default, moved with LUMENFLOW_CLI_DIST_CACHE
— see the config reference). Every success claim is
verified: the expected entry exists, the provenance sidecar is readable, every
declared output file is present, and provenance matches the current inputs.
FreshDistIncompleteArtifactError names which of those failed:
- A cached build could not be activated (a refused file removal, a full or read-only filesystem, a symlink inside the output directory). The command falls back to a real build on its own; no action is needed unless the real build then fails for the same environmental reason.
- A peer build did not leave a usable artifact. The command rebuilds instead of trusting the peer’s completion. If it repeats, another process is writing the same output directory outside the lifecycle.
- The build completed without replacing the output, so its provenance
cannot be republished. This is the one case that needs you: an incremental
build cannot replace an output it already considers current, so it can never
repair a missing or corrupt provenance sidecar and every retry fails
identically. Re-run the configured build with its cache disabled so it
re-executes — the error prints the exact command. Do not delete a
distdirectory that other checkouts read through; that empties the artifact those checkouts depend on while your build runs.
A poisoned or partially copied cache entry is rejected before activation rather than published over a working output, so a bad entry costs one rebuild, not a broken checkout. If you must discard the cache entirely, remove the cache root; it is rebuilt on demand and contains no state that is not reproducible from source.
Node version and CLI artifact coherence
Section titled “Node version and CLI artifact coherence”The CLI hashes source, dependencies, and the Node ABI together, so sessions
running different Node versions invalidate each other’s dist in a loop: pin
the engine version on every command. Treat ERR_MODULE_NOT_FOUND under dist
after a successful build as a stale build cache, not a code problem — remedy
it with a forced rebuild of the package, not a debugging session.
Gate Failures
Section titled “Gate Failures”Format check fails
Section titled “Format check fails”Symptom:
Fix:
Lint check fails
Section titled “Lint check fails”Symptom:
Fix:
- Read the error message to understand the issue
- Fix the code (don’t disable the rule unless necessary)
- Retry:
pnpm wu:prep --id WU-XXX
Common lint fixes:
| Error | Fix |
|---|---|
no-explicit-any | Add proper TypeScript types |
no-unused-vars | Remove the variable or prefix with _ |
exhaustive-deps | Add missing useEffect dependencies |
no-restricted-imports | Use the correct import path |
Type check fails
Section titled “Type check fails”Symptom:
Fix:
- Fix the first error (later errors often cascade from earlier ones)
- Save and check again
- Repeat until clean
Tests fail
Section titled “Tests fail”Symptom:
Fix:
- Run the failing test in isolation:
pnpm test src/__tests__/auth.test.ts - Debug: check test setup, mocks, and assertions
- Fix and retry
Common causes:
- Mocks not reset between tests (use
beforeEach) - Async tests not awaited
- Environment differences (CI vs local)
Pre-existing gate failures
Section titled “Pre-existing gate failures”If gates fail on code you didn’t change:
-
Verify the failure existed before your changes
-
Use a named gate skip only when the gate is explicitly skippable
-
Create a follow-up WU to fix the issue
WU State Issues
Section titled “WU State Issues”WU stuck in in_progress
Section titled “WU stuck in in_progress”Symptom: WU shows in_progress but worktree is gone or work is done elsewhere.
Fix:
Use restore first when the WU is active or recently active and its lane branch still exists. It
recreates the worktree without resetting WU status, branch, baseline/main metadata, or completion
evidence. Use reset for orphaned ready / in_progress state only after restore is impossible
or intentionally not wanted.
Current non-PR automatic wu:done publication builds and validates completion metadata in an
isolated temporary worktree, then publishes the exact commit without mutating checked-out main. If
remote acknowledgement is lost, it preserves that evidence; rerun the same command to prove and
retire an accepted publication or rebuild from the latest remote main. For historical residue from
older versions, run the read-only analyzer. If it proves that rollback completed but the index
retains only the stale completion tuple, use --action reconcile. Reconcile preserves every
worktree byte and refuses unrelated staged edits, unregistered worktrees, ambiguous projections, a
busy Git index, or missing transaction evidence. Never substitute a raw reset or manual index edit.
Orphan-done worktree repair does not clear a suffixed re-adoption worktree
Section titled “Orphan-done worktree repair does not clear a suffixed re-adoption worktree”Symptom: a done WU still has a leftover worktree under worktrees/, but the leftover directory
uses a suffixed name from re-adoption (<lane-kebab>-<wu-id>-r2, -p0, …) rather than the
canonical <lane-kebab>-<wu-id> name — for example a wu:done cleanup step that failed partway
through an ownership handoff. wu:repair --id WU-XXXX reports Successfully repaired, but
wu:repair --id WU-XXXX --check still reports ORPHAN_WORKTREE_DONE, and every wu:claim in the
same lane is refused by the lane’s orphan pre-flight.
Fix: none needed — wu:repair resolves every worktree registered under git worktree list
that matches the WU id (by directory basename or branch name), not only the canonical directory
name, so a suffixed re-adoption worktree is found and removed in the same pass as the canonical
one:
Before removing a matched worktree, the repair quarantine-copies its .lumenflow/memory/ store (if
present) under .lumenflow/quarantine/worktrees/<worktree-name>/memory/ and records the copy
location in .lumenflow/quarantine/worktrees/cleanup.jsonl, so a shared-memory node written inside
the leftover worktree is never silently discarded. The repair reports success only once
git worktree list no longer matches the WU id at all; if a matched worktree cannot be removed (for
example it is git worktree locked), it reports a named failure listing every path it examined
instead of a false success.
WU status mismatch
Section titled “WU status mismatch”Symptom: backlog.md says one status, WU YAML says another.
Fix:
wu:release reports WU YAML / state-store divergence
Section titled “wu:release reports WU YAML / state-store divergence”wu:release compares the WU YAML status with the event-sourced state store before any release
mutation. When they disagree, it stops without changing the YAML, event log, derived docs, branch,
or lane lock and names both statuses, for example:
Run the named repair, review its output, then rerun the intended release command. Do not use a release retry or a force flag to choose one state source over the other.
wu:rebase refuses a legacy claim with no claimed_branch
Section titled “wu:rebase refuses a legacy claim with no claimed_branch”Symptom: wu:rebase fails closed because the WU documents carry no claimed_branch, and
wu:repair --claim refuses first with:
Claims minted before the branch-binding mechanism have no claimed_branch in either the canonical
or the worktree document, and their local baseline_main_sha is often stale because the branch has
not been rebased since it was claimed. The repair needed the rebase, and the rebase needed the
repair.
Fix: run the claim repair as the recorded claim owner, with --base-dir naming the canonical
main checkout. It now reconciles the binding and the baseline together:
--check reports the absent binding and, when it applies, the divergent baseline as repairable.
It never advertises a repair the apply path would reject: both resolve the canonical baseline
through the same authority, so a well-formed but unresolvable object name fails --check closed
instead of being reported repairable. The apply path writes the live attached branch into both
documents and refreshes the local baseline_main_sha to the canonical value in the same commit,
so a half-repaired claim document is never published.
Lane already has a WU in progress
Section titled “Lane already has a WU in progress”Symptom:
Fix:
- Check if WU-040 is truly in progress:
pnpm wu:status --id WU-040 - If blocked, mark it:
pnpm wu:block --id WU-040 --reason "Waiting for API" - If done, complete it:
pnpm wu:done --id WU-040 - If orphaned, recover:
pnpm wu:recover --id WU-040 --action reset
Lane lock not auto-clearing despite dead PID
Section titled “Lane lock not auto-clearing despite dead PID”Symptom:
The lock holder’s process is no longer running, but the lock is not auto-cleared.
Explanation: Lane locks persist after the wu:claim process exits. A dead PID alone does not trigger auto-clearing — the lock must also be older than 2 hours (stale). This prevents a second claim from stealing a legitimately held lane.
Fix:
- If the lock is recent (less than 2 hours old), it is likely still valid. Complete or release the existing WU first.
- If the lock is genuinely abandoned, unlock manually:
- Locks older than 2 hours with a dead PID will auto-clear on the next
wu:claimattempt.
Evidence-only state drift during wu:done
Section titled “Evidence-only state drift during wu:done”Symptom:
But git status shows only .lumenflow/state/packs/software-delivery/wu-events.jsonl as modified (from a recent wu:brief run).
Cause: Running wu:brief records evidence to wu-events.jsonl. If other WUs merged to main and triggered auto-rebase, the rebase could fail because this workflow-generated file was dirty.
Fix: As of v3.19.0, wu:done auto-rebase automatically preserves and restores wu:brief evidence when wu-events.jsonl is the only dirty file. If you’re on an older version, commit the evidence file before retrying:
Ownership violation on wu:block or wu:release
Section titled “Ownership violation on wu:block or wu:release”Symptom:
or:
Cause: As of v3.19.0, state-mutating commands validate session ownership. You’re trying to modify a WU that belongs to another agent session.
Fix:
- Don’t modify another agent’s WU to free a lane. Wait for the owning WU to complete or block itself.
- If you have legitimate reason for cross-session recovery, use the override:
All overrides are audited to .lumenflow/ownership-override-audit.log.
Worktree Issues
Section titled “Worktree Issues”A claimed worktree cannot run wu:brief, wu:edit or wu:prep
Section titled “A claimed worktree cannot run wu:brief, wu:edit or wu:prep”Symptom:
What it means: wu:claim refused to report success for a worktree it could not prove is
usable. This is the automatic bootstrap contract: a claim either hands you a worktree that runs the
governed commands, or it does not complete.
wu:claim performs three steps, and only reports success after all three:
- Seed generated artifact roots from the main checkout, following the workspace dependency
graph in deterministic topological order, so a dependency’s artifacts land before a dependent’s.
An artifact is refused rather than copied when it resolves outside the main checkout or when its
provenance records a different Node major or ABI than the claim is running. Mutable
node_modulesstate is never copied. - Install worktree-local dependencies with the immutable install for your package manager
(
pnpm install --frozen-lockfile,npm ci, …). This resolves dependencies; it does not build or validate the artifacts those dependencies expose. - Verify by really running
wu:brief --help,wu:edit --helpandwu:prep --helpinside the worktree, through the checkout-local dependency graph. The first of these builds a coherent local CLI dist if one is owed.
Step 3 exists because step 2 can report success over an incoherent artifact graph. Executing the command is the only check that distinguishes artifact presence from artifact coherence.
Fix:
The failed claim rolls back atomically, so no in_progress WU, lane lock, branch or worktree is
left behind and nothing needs cleaning up first.
Note on --skip-setup: it opts out of all three steps. It is read-only by design — it seeds
nothing, installs nothing, builds nothing and therefore certifies nothing — and a --skip-setup
worktree is not certified to run wu:brief, wu:edit or wu:prep. It still fails closed when the
main checkout it reuses has unsafe dependency links.
Note on --help: <command> --help skips the build when this checkout already has a CLI dist,
but it never answers from another checkout’s dist. What help is being asked in a fresh worktree is
whether this checkout can run the command; a file in the main checkout has never been evidence
about this one. With no local dist, help builds one.
Worktree not found
Section titled “Worktree not found”Symptom:
Fix:
Changes made in wrong directory
Section titled “Changes made in wrong directory”Symptom: You made changes in main instead of the worktree.
Fix:
Worktree has merge conflicts
Section titled “Worktree has merge conflicts”Symptom: wu:rebase pauses after reporting ordinary content conflicts.
Fix:
The governed continuation verifies the active WU, lane branch, worktree and claim, integration
target and SHA, replayed commit, paused HEAD, unresolved set, and staged path scope. It never
selects ours or theirs. If one additional reviewed path must be staged, authorize it explicitly
with repeatable --allow-staged <repo-relative-path> flags. To discard the attempt and restore the
pre-rebase branch state, run pnpm wu:rebase --id WU-042 --abort.
Git Issues
Section titled “Git Issues”wu:done fails with “not a fast-forward”
Section titled “wu:done fails with “not a fast-forward””Symptom:
Cause: Main has new commits since you started your WU.
Fix:
wu:done fails with “Worktree has uncommitted changes”
Section titled “wu:done fails with “Worktree has uncommitted changes””Symptom:
Cause: wu:done requires a clean, committed worktree before it can merge.
Fix:
If the changes were accidental, restore the files, then retry.
Hooks block my commit
Section titled “Hooks block my commit”Symptom:
Cause: You’re trying to commit WU work from the main directory.
Fix:
Commit message missing WU ID
Section titled “Commit message missing WU ID”Symptom:
Fix: Include the WU ID in the commit message, for example:
Branch drift warning
Section titled “Branch drift warning”Symptom:
Fix:
Parallel completions detected
Section titled “Parallel completions detected”Symptom:
Cause: Other WUs merged to main while your WU was in progress.
Fix: Use the governed lane rebase from the WU worktree, then retry:
Rebase a worktree pinned to an older CLI
Section titled “Rebase a worktree pinned to an older CLI”If a long-lived worktree is pinned to an older CLI (such as 6.0.6 or 6.0.8), its wu:rebase may
hard-abort on a spec-YAML content conflict because older versions did not pause for governed
conflict resolution. Run the newer CLI from the main checkout and target the old worktree with
--base-dir:
This uses the main checkout only for its newer CLI; --base-dir keeps the rebase, conflict state,
and Git operations scoped to the worktree. Do not upgrade or reinstall the old worktree’s pinned
dependencies to get the newer CLI, and do not resolve or stage paths that the command did not
report. Use --dry-run first to inspect the rebase, or --abort with the same --base-dir to
discard a paused rebase. Once it succeeds, run pnpm wu:prep in the worktree and finish with
wu:done from main.
Rebase audit evidence appears
Section titled “Rebase audit evidence appears”When wu:done resolves governed metadata conflicts during an automatic rebase, LumenFlow appends
an audit row to .lumenflow/meta-rebase-audit.ndjson. The file is append-only local evidence. It
is intentionally ignored by Git and remains on disk across lumenflow init and
lumenflow:upgrade.
A manually resolved wu:rebase content session appends a terminal row to the same file after a
validated --continue or --abort. It includes old and final commits, target ref and SHA, all
conflicted paths, explicitly authorized staged paths, resolver identity, timestamps, and the
continued or aborted outcome. The ignored pause record at
.lumenflow/state/packs/software-delivery/wu-rebase-conflict.json remains available while the
rebase is paused and is cleared after the terminal operation succeeds.
Do not commit the audit and do not delete it to satisfy gates. Incremental format checks exclude
only this exact normalized runtime path because Prettier does not parse NDJSON; changed source files
are still formatted and checked normally. If an older workspace shows the file as untracked, run
lumenflow:upgrade to reconcile .gitignore. Reconciliation adds the canonical ignore entry
without deleting or rewriting existing audit bytes.
Control-plane runtime files keep the checkout dirty
Section titled “Control-plane runtime files keep the checkout dirty”The control-plane sidecar writes its latest-tick snapshot and durable outbox under
.lumenflow/state/. These files are local runtime state, including when LumenFlow runs inside a
nested workspace. Run pnpm lumenflow:upgrade --latest to reconcile the canonical root and nested
ignore rules.
If an older installation already tracked
.lumenflow/state/control-plane-sidecar-last-tick.json, upgrade removes the file from Git’s index
without deleting or rewriting the working copy. It does not untrack repository-bound lifecycle
evidence: wu-events.jsonl, migration-complete.json, and WU done stamps remain versioned.
Software Delivery State Namespace
Section titled “Software Delivery State Namespace”As of the state-namespace migration (WU-3378), Software Delivery state (the WU
event log, stamps, archive, merge lock, telemetry, flow log, incidents, and
commands log) resolves under a pack-owned namespace instead of generic shared
.lumenflow/<name> paths:
Agent session state (.lumenflow/sessions/) stays at the shared kernel path —
it’s a cross-pack contract with the agent-runtime pack and is not part of
this namespace.
Detection and migration: every CLI command checks for the sentinel file
above before running main(). If it’s missing and legacy .lumenflow/state,
.lumenflow/stamps, etc. exist, LumenFlow runs a one-way, atomic migration:
it copies the legacy content into the namespace through a private staging
directory, then promotes it with a single atomic rename, then records the
sentinel (source digest, target schema version, per-category file counts —
no secrets). The legacy directories are never deleted or written back to
— they remain on disk as a historical record. Once the sentinel exists,
subsequent CLI invocations skip re-verification (a single file-existence
check), so steady-state startup cost is unaffected.
Recovery: the migration is fail-closed. If it’s interrupted mid-run, the
next invocation either resumes cleanly (a crash before the atomic promote
just leaves disposable scratch space that gets cleared) or finalizes cleanly
(a crash after the promote but before the sentinel just needs the sentinel
written — no data is re-copied or duplicated). If it detects the legacy
source has changed since a prior successful migration (tampering or manual
edits), or that the target namespace already contains data that doesn’t match
what the legacy source would produce, it refuses to proceed and leaves both
locations untouched — inspect .lumenflow/state/packs/software-delivery/
manually before retrying.
Removal: lumenflow:uninstall cleans up both the new namespace and any
remaining legacy directories.
Configuration: workspace.yaml’s software_delivery.state.* fields (all
except base, the kernel-shared .lumenflow root) may still be overridden,
but overrides must resolve inside the pack namespace — an override that
points outside .lumenflow/state/packs/software-delivery is rejected at
startup instead of silently redirecting state to a shared writer path.
CLI Issues
Section titled “CLI Issues”Command not found: wu-create
Section titled “Command not found: wu-create”Symptom:
Fix:
Config validation errors
Section titled “Config validation errors”Symptom:
Fix:
- Check the error message for the specific field
- Compare with the Configuration Reference
- Fix the YAML syntax or values
Validate without running:
Memory checkpoint fails
Section titled “Memory checkpoint fails”Symptom:
Fix:
wu:done warns about missing checkpoints
Section titled “wu:done warns about missing checkpoints”Symptom:
Fix: Create checkpoints during long sessions:
Context Validation Errors
Section titled “Context Validation Errors”LumenFlow commands include context-aware validation that checks your location, WU status, and git state before running. When validation fails, you’ll see an error with a copy-paste fix.
WRONG_LOCATION
Section titled “WRONG_LOCATION”Symptom:
Fix: Run the command from the correct location. wu:done runs from main; wu:prep runs from the worktree.
WRONG_STATUS
Section titled “WRONG_STATUS”Symptom:
Fix: Claim the WU first: pnpm wu:claim --id WU-042 --lane "Your Lane"
GIT_DIRTY
Section titled “GIT_DIRTY”Symptom:
Fix: Commit your changes before running wu:prep:
Configuring Validation
Section titled “Configuring Validation”You can adjust validation behavior in workspace.yaml:
Enforcement Hooks
Section titled “Enforcement Hooks”pnpm lumenflow:integrate is a deprecation no-op as of WU-3543 — it prints migration guidance and exits 0 without writing any files. LumenFlow no longer generates or manages AI-client-specific enforcement hooks. If your project has a .claude/hooks/ directory from an older LumenFlow version, it is a snapshot — your file now, never regenerated or touched by LumenFlow again. Adapting an enforcement-hook layer into your own tool is a repo-owner task; see AI Coding Assistant Integrations for a copyable example.
If a hook blocks your operation, check:
- Are you in a worktree? Hooks block edits outside worktrees. Run
pwdand verify. - Do you have a claimed WU? Some hooks require an active WU for edits.
- Is the file in your code_paths? Hooks may restrict edits to scoped files.
See Agent Safety for the full enforcement architecture.
pnpm lumenflow:doctor reports lifecycle enforcement as enforced,
non-compliant-disabled, missing, stale, tampered, or unavailable. For every remediable
non-compliant state, run pnpm lumenflow:enable; it atomically writes the generic delegators and
digest-bound manifest, preserving marker-external user bytes. unavailable means repository storage
cannot be read safely: restore storage access before retrying. Only enforced is certifying.
Disabled and uninstalled consumers cannot claim lifecycle certification.
Local remediation assumes the process follows repository policy. A hostile unsandboxed process with the same OS-user authority can replace local code, hooks, or receipts; preventing that requires an OS sandbox or protected remote/server authority.
Bootstrap And Local Runtime Prerequisites
Section titled “Bootstrap And Local Runtime Prerequisites”Clean WU worktrees may not have packages/@lumenflow/cli/dist built locally. Root LumenFlow package
scripts should route through node tools/cli-entry.mjs <entry> so commands can use an existing main
checkout dist or build on demand instead of failing with MODULE_NOT_FOUND.
If a package script edit adds or changes LumenFlow CLI aliases, run:
The live probes cover common agent entry points such as mem:create, orchestrate:monitor,
lumenflow:commands, and lumenflow:setup-prereqs.
Before local database or local model workflows, run:
The report checks Supabase CLI, Docker, and Supabase local stack readiness when Supabase config or
deps are detected. It also checks Ollama binary, OpenAI-compatible local API, and configured model
readiness when Ollama deps or OLLAMA_* env vars are present.
Official setup references:
- Supabase local development
- Supabase CLI getting started
- Ollama API introduction
- Ollama OpenAI compatibility
The prereq report intentionally omits local service keys and token-shaped values. Do not paste raw
supabase start, .envrc, or provider-token output into issues, WU notes, or prompts.
Still Stuck?
Section titled “Still Stuck?”If these solutions don’t help:
- Check logs:
cat .lumenflow/state/packs/software-delivery/flow.log - Run with debug:
DEBUG=lumenflow:* pnpm wu:done --id WU-042 - Review the FAQ for common pitfalls.
Include in your question:
- The exact error message
- Your
workspace.yaml(redact secrets) - Output of
pnpm wu:status --id WU-XXX - Your Node.js version:
node --version