Troubleshooting
Common issues and how to fix them. If your issue isn't listed here, use the /ndx-feedback skill in your assistant (Claude Code or Codex) to report it — it'll file a GitHub issue with your environment details automatically.
ERR_MODULE_NOT_FOUND on every ndx command
Problem: Any ndx command crashes immediately with a stack trace like:
Error [ERR_MODULE_NOT_FOUND]: Cannot find module
'.../node_modules/assistant-assets/index.js' imported from
'.../node_modules/@n-dx/core/claude-integration.js'Cause: You are on @n-dx/core 0.3.x, which shipped with an import path that escaped the published tarball. The referenced file was never included, so Node fails while linking the module graph — before any ndx code runs. Fixed in 0.4.0.
Reinstalling alone often does not help. pnpm records a caret range in its global manifest, and for 0.x versions ^0.3.1 means >=0.3.1 <0.4.0 — so pnpm add -g @n-dx/core and pnpm update -g both re-resolve inside the broken 0.3 line and can never reach the fix.
Fix: reinstall with an explicit @latest tag, which pins past the recorded range:
# pnpm — remove first so the stale caret range is dropped from the manifest
pnpm remove -g @n-dx/core
pnpm add -g @n-dx/core@latest
# npm
npm i -g @n-dx/core@latestThen confirm the version actually changed:
ndx --version # expect 0.4.0 or newerTwo things to watch for:
- Run these from outside an n-dx checkout. The repo's
.npmrcsetsminimum-release-age, and pnpm reads a local.npmrceven for-goperations — from inside the repo it will refuse recent releases. - Don't switch package managers to upgrade. Installing with npm when your existing global install came from pnpm leaves two
ndxshims onPATH. Whichever resolves first wins, sondx --versioncan keep reporting the old version even though the upgrade succeeded. Upgrade with the same manager you installed with, or remove the other install first.
"Unknown command" when running rex/sourcevision/hench commands
Problem: Running rex plan or sourcevision init fails with "unknown command."
Cause: Some commands are orchestrator-level and only available through ndx. The package CLIs (rex, sourcevision, hench) only expose their own domain commands.
Fix: Use ndx for all commands:
ndx plan . # not "rex plan"
ndx work . # not "hench run"
ndx analyze . # not "sourcevision analyze"Run ndx --help to see all available commands.
Init prompts for provider on re-run
Problem: Running ndx init . on an already-initialized project still asks which LLM provider to use.
Cause: The init flow may not detect your existing configuration if .n-dx.json is missing or malformed.
Fix: Pass the provider explicitly to skip the prompt:
ndx init --provider=claude .Or check that .n-dx.json exists with a valid llm.vendor field.
API key / CLI authentication failures
Problem: Commands fail with authentication errors even though you've configured a provider.
Cause: The API key or CLI path isn't set, or the environment variable isn't exported.
Fix:
# For Claude API mode
ndx config llm.claude.api_key sk-ant-... .
# or
export ANTHROPIC_API_KEY=sk-ant-...
# For Claude CLI mode
ndx config llm.claude.cli_path claude .
claude login
# For Codex
ndx config llm.codex.cli_path codex .
codex loginCheck current config with ndx config .
Claude init / vendor preflight error codes
When ndx init --provider=claude . or ndx config llm.vendor claude . fails before setup completes, use the emitted code to pick the right fix:
NDX_CLAUDE_PREFLIGHT_NOT_INSTALLED: Claude Code is not installed or the configured executable does not exist. Install it withnpm install -g @anthropic-ai/claude-code, then verify withclaude --version.NDX_CLAUDE_PREFLIGHT_NOT_ON_PATH:ndxwas given a command name it cannot resolve from the current shell. Checkcommand -v <your-configured-command>, fixPATH, or setllm.claude.cli_pathto an absolute executable path.NDX_CLAUDE_PREFLIGHT_AUTH_REQUIRED: Claude is installed but not authenticated. Runclaude loginand retry.NDX_CLAUDE_PREFLIGHT_INVOKE_FAILED: Claude appears present, butndxcould not launch a usable executable. Verify the exact binaryndxresolves withcommand -v claudeorndx config llm.claude.cli_path, then run that executable directly with--versionbefore retrying.
Dashboard shows blank PRD tree
Problem: The Tasks view in the web dashboard shows nothing.
Cause: If all tasks are completed and the status filter defaults to hiding completed items, the tree appears empty.
Fix: This has been fixed in recent versions — the default now shows all items. If you're on an older version, click the status filter chips to enable "Completed" visibility, or upgrade:
npm i -g @n-dx/core@latestPort conflict with ndx start
Problem: ndx start fails because port 3117 is already in use.
Cause: Another instance of the server (or another application) is using the default port.
Fix:
# Use a different port
ndx start --port=3118 .
# Or stop the existing server
ndx start stop .MCP tools not updating after rebuild
Problem: After rebuilding packages, MCP tools in Claude Code or Codex still show old schemas or behavior.
Cause: The HTTP MCP server caches tool schemas at startup. Rebuilding packages doesn't automatically reload them.
Fix: Restart the server:
ndx start stop .
ndx start .If using stdio MCP transport, re-run init to regenerate configs:
ndx init . # re-registers Claude MCP servers and regenerates the Codex config (.codex/config.toml)For Claude Code specifically, you can also remove and re-add servers manually:
claude mcp remove rex
claude mcp remove sourcevision
ndx init .Analysis takes a long time
Problem: ndx analyze runs for several minutes on large codebases.
Cause: The analysis pipeline runs multiple passes including LLM-powered enrichment.
Fix: Use lite mode for faster results (skips LLM enrichment):
ndx analyze --lite .For the full multi-pass analysis, --deep is the default. The first run is slowest; subsequent runs are faster because unchanged files are cached.
See the Skills Reference for the workflow slash commands available in your assistant session, including /ndx-feedback for filing issues.
Codex output and usage diagnostics
Malformed Codex output (parse fallback)
Symptoms:
- Task run does not crash, but summary contains raw payload text.
- Warnings appear for missing/unknown block types.
Verify:
rg -n "normalizeCodexResponse|Codex block missing type|Unknown Codex block type" packages/hench/src/agent/lifecycle/cli-loop.tsExpected:
- Matches exist for
normalizeCodexResponse. - Warning strings are present:
Codex block missing type; ignoring block.andUnknown Codex block type "..."
pnpm --filter hench exec vitest run tests/unit/agent/codex-normalization.test.tsExpected:
- Test names include
truncated JSON payload falls back to plain textandapplies deterministic fallback behavior for malformed fixtures. - Suite passes without throwing on malformed payloads.
Operational signal during a run:
[Warn] Codex block missing type; ignoring block.[Warn] Unknown Codex block type "<type>" ignored.
Remediation:
- If you wrap
codex exec, ensure blocks include atypeand text fields (text,content,delta, oroutput_text). - Plain text output is supported; malformed JSON is treated as plain text fallback.
Missing usage fields / token mismatch in Codex mode
Symptoms:
hench showreports0 in / 0 outdespite a non-empty response.- Token budget behavior looks lower than expected for that turn.
Verify:
rg -n "mapCodexUsageToTokenUsage|codex_usage_missing|input_tokens|prompt_tokens|completion_tokens|total_tokens" packages/hench/src/agent/lifecycle/token-usage.ts packages/hench/src/agent/lifecycle/cli-loop.tsExpected:
- Mapping exists for:
- input:
input_tokens | prompt_tokens | input - output:
output_tokens | completion_tokens | output - total:
total_tokens | total(fallback toinput + output)
- input:
- Diagnostic key
codex_usage_missingis present. - Warning text exists:
Codex response omitted usage; token accounting defaulted to zero.
pnpm --filter hench exec vitest run tests/unit/agent/token-usage.test.tsExpected:
mapCodexUsageToTokenUsagecases pass, including:- nested
response.usagemapping - zeroed usage with
codex_usage_missingwhen usage is absent/empty
- nested
ndx hench show <run-id> --format=json .Expected when usage fields are missing:
tokenUsage.input = 0tokenUsage.output = 0turnTokenUsagestill records the turn with zeros.
Remediation:
- Prefer emitting
usage.input_tokensandusage.output_tokensfrom Codex-compatible wrappers. - If upstream only provides
prompt_tokens/completion_tokens, those are already mapped. - If no usage fields are available, zero fallback is intentional; treat the warning as a data-quality signal.
