Troubleshooting
This page is organized by what you see. Find your symptom; follow the fix. Most issues are auth, model routing, or wizard state — those sections come first.
If nothing here helps:
- Run
modulatio doctorand read its output carefully — it catches the common stuff - Check
<vault>/.usage.jsonlfor the most recent agent calls and their failure shapes - Open an issue with the
doctoroutput, the relevant lines from.usage.jsonl, and a brief description of what you were trying to do
Install & first-run
Section titled “Install & first-run”modulatio: command not found
Section titled “modulatio: command not found”Symptom: install completes but modulatio --version fails.
Cause: venv not activated, OR install was non-editable.
# Activatesource ~/modulatio/.venv/bin/activatewhich modulatio # should show a path inside the venv
# If still missing, re-run editable installuv pip install -e ".[dev]"ImportError after install
Section titled “ImportError after install”Cause: Python is outside the tested range. A dependency without a wheel for the active Python (commonly lancedb, fastembed, or litellm) likely failed its source build silently.
Fix: rebuild the venv on /usr/bin/python3.12:
deactivaterm -rf ~/modulatio/.venv/usr/bin/python3.12 -m venv ~/modulatio/.venvsource ~/modulatio/.venv/bin/activateuv pip install -e ".[dev]"lancedb or pyarrow wheel-build crash during install
Section titled “lancedb or pyarrow wheel-build crash during install”Cause: missing build essentials.
Fix:
# Debian / Ubuntusudo apt-get install -y build-essential cmake pkg-config
# Fedora / RHELsudo dnf groupinstall -y "Development Tools"sudo dnf install -y cmake pkg-config
# macOSxcode-select --installThen retry uv pip install -e ".[dev]".
Wizard quit mid-step; partial state on disk
Section titled “Wizard quit mid-step; partial state on disk”The wizard persists in-flight state to ~/.config/modulatio/setup-state.json. Re-running modulatio setup resumes from where you left off.
To start fresh:
rm -f ~/.config/modulatio/setup-state.jsonmodulatio setupAuth & providers
Section titled “Auth & providers””401 Unauthorized” or “Invalid API key”
Section titled “”401 Unauthorized” or “Invalid API key””- Confirm the key was copied without a trailing newline:
python3 -c "import os; k=os.environ.get('XAI_API_KEY',''); print(repr(k))"— should not show\nat the end. - For Anthropic: confirm key starts with
sk-ant-. Other prefixes (sess-, etc.) are session tokens, not API keys. - For new keys: wait 30-60 seconds for propagation; some providers cache key-validity briefly.
- Confirm the right env var is set in
<vault>/.env(key name should match what the model entry’sauth_value_reffield expects).
”Token expired” / “OAuth refresh failed”
Section titled “”Token expired” / “OAuth refresh failed””The OAuth refresher tried to renew a token and the provider returned an error.
- Check
auth listfor status:modulatio auth list - Re-auth manually:
modulatio auth clear oauth_anthropicthen run any command that uses Anthropic (it’ll trigger re-auth flow) - For Pro/Max OAuth: confirm your subscription is still active (sometimes a billing lapse silently invalidates tokens)
“Model not found” / “Unknown model”
Section titled ““Model not found” / “Unknown model””Cause: the model ID doesn’t match what the provider lists.
- For OpenRouter, the format is
openrouter/<provider>/<model-id>—openrouter/anthropic/claude-haiku-4-5, not justclaude-haiku-4-5 - For Ollama: list models with
ollama list; the LiteLLM-formatted ID isollama/<name-shown> - For LM Studio: the ID is shown in the Server tab logs when a model is loaded
- For first-party (xAI, Anthropic, OpenAI): consult the provider’s current model list — names change occasionally
Update the model entry: modulatio models edit <label>.
Local Ollama / LM Studio not auto-detected by wizard
Section titled “Local Ollama / LM Studio not auto-detected by wizard”# Confirm Ollama is upcurl http://localhost:11434/api/tags
# Confirm LM Studio is upcurl http://localhost:1234/v1/modelsIf both work but the wizard doesn’t auto-detect, add manually via modulatio models add with the explicit URL.
”Bartowski GGUF tool calls fail silently”
Section titled “”Bartowski GGUF tool calls fail silently””Some bartowski-published GGUFs ship without a tool-calling chat template, so tool-using producers (research, run_shell) appear to work but emit no tool calls.
Fix:
- Pull an alternative quant that includes the template, OR
- Set
supports_tools: falseon that model entry (dispatch will route tool tasks to a different model)
Plan execution
Section titled “Plan execution”Plan stuck in awaiting-approval
Section titled “Plan stuck in awaiting-approval”You haven’t approved or rejected. Approve via:
- TUI → tell the Leader in the LEADER chat (e.g.
approve) - Telegram → reply with the prescribed phrase
- CLI →
modulatio project approve <plan-id>
If you don’t intend to run the plan, cancel: modulatio project cancel <plan-id>.
Plan paused; reason unclear
Section titled “Plan paused; reason unclear”Check <vault>/projects/<code>/runs/<id>/leader-notes.md — last line usually states the pause reason.
Also check <run>/divergence-log.jsonl for any divergence flags.
Common pause reasons + fixes:
- “QC rejected 3+ times” → producer model can’t hit standard. Escalate model or rewrite the standard.
- “Auth refresh failed” → re-auth the provider; resume.
- “Divergence flag exceeded threshold” → producer claims and QC verdicts diverged on multiple tasks. Read divergence-log.jsonl for specifics; usually means the producer is over-claiming and the work isn’t actually progressing.
Plan halted due to budget
Section titled “Plan halted due to budget”modulatio project edit-budget <plan-id> --tokens 1000000 # bump capmodulatio project resume <plan-id>Or accept the partial output and finalize:
modulatio project finalize <plan-id> --as-donePlan keeps cycling: produce → QC reject → re-produce → reject
Section titled “Plan keeps cycling: produce → QC reject → re-produce → reject”Three causes ranked by frequency:
- Standard too implicit. QC knows the artifact “feels off” but the standard doesn’t say what to fix. Add an explicit rule:
modulatio-standards add <kind> "...". - Producer model too weak. Escalate to a stronger model; the rejected drafts should pass on the new model.
- Standard contradicts task constraint. E.g., standard says “1000 words minimum” but task says “keep it under 400.” Resolve at the task level (task-level constraint wins per QC’s conformance hierarchy).
”Plan reached done but the output is wrong”
Section titled “”Plan reached done but the output is wrong””QC accepted the artifacts, which means they passed the standards as configured.
- Confirm the standards exist + are loaded:
modulatio-standards list --kind <kind> - If the standards exist but the output still looks wrong: the standards are too lenient, OR the QC model is too lenient.
- Tighten standards or swap to a stronger QC model, then re-plan.
”Planning over-decomposes simple objectives”
Section titled “”Planning over-decomposes simple objectives””Symptom: “draft one essay” turns into a 10-task plan with platform-building subtext.
Fix: phrase the objective as a noun-phrase naming the artifact:
"Draft three essays on stoicism" ✓"Analyze stoicism via essays" ✗ (reads as "build platform")Or add a project standard: "Plans should not exceed 5 sub-objectives unless explicitly justified".
Daemon & TUI
Section titled “Daemon & TUI”Copy/paste between the TUI and other apps doesn’t work
Section titled “Copy/paste between the TUI and other apps doesn’t work”The TUI reaches the OS clipboard through a system backend. On Linux, install one:
sudo apt install xclip # Debian/Ubuntu (X11)sudo apt install wl-clipboard # Waylandmodulatio doctor shows whether a backend is detected, and modulatio setup
offers to install it. macOS and Windows work out of the box. Without a backend,
Ctrl+C still copies via OSC 52 — but that depends on your terminal honoring
clipboard writes (many disable it by default, and it often doesn’t survive a
remote desktop), and Ctrl+V paste from the OS clipboard is unavailable. A
backend is the reliable path.
Daemon won’t start
Section titled “Daemon won’t start”modulatio daemon statusIf “stopped” but modulatio daemon on returns success and status still says stopped, check logs at ~/.config/modulatio/daemon.log.
Common causes:
- Stale lock file from a crashed previous daemon:
rm ~/.config/modulatio/daemon.lockand retry - Socket already in use:
ps aux | grep modulatio-daemonto find the rogue process
TUI shows “no daemon connection”
Section titled “TUI shows “no daemon connection””Daemon isn’t running. Start it: modulatio daemon on.
If the daemon is running but the TUI still can’t connect, the socket location is mismatched. Check MODULATIO_DAEMON_SOCKET env var on both daemon and TUI sides; they need to match.
TUI freezes or shows partial output
Section titled “TUI freezes or shows partial output”Usually a Textual rendering bug under specific terminals. Try:
- Resize the terminal window (forces full redraw)
Ctrl+L(textual’s clear+redraw)- Quit (
q) and re-launch
Worst case: tput reset to fully reset the terminal.
Memory & embeddings
Section titled “Memory & embeddings””MiniLM model not found” / semantic routing fails
Section titled “”MiniLM model not found” / semantic routing fails”The embedding cache wasn’t downloaded.
Fix: the wizard’s step 8 handles this. To trigger manually:
python3 -c "from fastembed import TextEmbedding; TextEmbedding('sentence-transformers/all-MiniLM-L6-v2')"This downloads the model on first call.
”QC pool ACL violation”
Section titled “”QC pool ACL violation””QC pool writes are restricted to QC + Leader. If a producer agent tries to write, you’ll see this.
Cause: usually a mis-configured custom agent with a role description that overlaps QC’s. Rename the role description or remove conflicting skills.
Telegram
Section titled “Telegram””Telegram notifications not arriving”
Section titled “”Telegram notifications not arriving””modulatio telegram test # confirms token + chat ID workmodulatio telegram status # shows config stateIf test succeeds but plan notifications don’t arrive: check that the plan’s project has notify_telegram: true (default). Per-project notification preferences live in <vault>/projects/<code>/config.json.
”Telegram approval reply not recognized”
Section titled “”Telegram approval reply not recognized””Plan-approval replies via Telegram are matched against specific phrases (yes, approve, cancel, revise: ...). Random text won’t trigger an approval action — the bot should reply with a usage hint.
If you don’t get a usage hint either, the bot isn’t reaching the daemon. Check modulatio daemon status and the daemon log.
Provider-specific
Section titled “Provider-specific”Anthropic: “Pro/Max OAuth token rejected”
Section titled “Anthropic: “Pro/Max OAuth token rejected””Sometimes Pro/Max OAuth tokens silently lose access (provider-side change, attribution policy update, etc.). Mitigations:
- Switch the affected model entry to
api_keyauth (always works as long as the key is valid) - Or use
cli_subprocess(callsclaudebinary; uses Claude Code attribution, fully TOS-safe)
xAI: “grok-4.3-latest empty response”
Section titled “xAI: “grok-4.3-latest empty response””Known intermittent issue. Fallback chain handles it if configured. The watchdog will alert if it exceeds 3+ events in 24h. Mitigations:
- Pin a different default (
xai/grok-4-1-fastis rock-solid) - Or add
xai/grok-4-1-fastto the fallback chain so empty-response triggers fallback instead of error
Ollama: “model loaded but inference fails / hangs”
Section titled “Ollama: “model loaded but inference fails / hangs””For very large models (>50 GB):
- Reduce concurrent:
OLLAMA_NUM_PARALLEL=1 ollama serve - Disable mmap: model-specific Modelfile setting
For Pascal-era GPUs (Tesla P40, etc.): pin a compatible CUDA runtime; CUDA 12.x has regressed for Pascal in some Ollama versions.
Version-specific
Section titled “Version-specific””context-budget exhausted for … — Decompose it”
Section titled “”context-budget exhausted for … — Decompose it””Symptom: a CRITICAL ticket fires with the title “context-budget exhausted for <task-id> (…, model <model>)”. The task is BLOCKED.
Cause: Modulatio’s catch — a producer call’s prompt + context exceeded the model’s window even after Layer 2’s compression pass. Re-running with the same prompt would hit the same wall.
Fix: read the ticket body. It carries the checkpoint path + decompose-required framing. Two paths:
- Approve to auto-decompose. Leader-reflect’s
revise-majoroutcome splits the offending sub-objective into smaller pieces. Daemon picks up the revised plan on the next tick. - Decline if the work is genuinely too big for one phase. Production-scale efforts queue for a later release — see Roadmap.
The checkpoint at the path in the ticket body is an audit + decomposition input — NOT a re-input source. Don’t try to resume from the checkpoint manually; that’s recovery work the engine doesn’t yet support.
Soft-warn logs (“context-budget soft-warn: N/M tokens (X% of cap) …”)
Section titled “Soft-warn logs (“context-budget soft-warn: N/M tokens (X% of cap) …”)”Symptom: WARNING lines show up in your daemon’s stderr from modulatio.context_budget logger.
Cause: a call landed in the 70-80% band of the model’s window. This is early signal, not an error. The call proceeded normally; the engine flagged it so you could see work trending toward the compression band.
Fix: usually nothing. If you see soft-warn lines reliably in the same place, that sub-objective is over-scoped and a revise-major is in your future. Pre-empt by tightening the sub-objective scope in the next plan iteration.
If your monitoring parses logs programmatically, filter on modulatio_event="context_budget_soft_warn" to ignore them.
”plan has X tasks — exceeds the per-goal task cap”
Section titled “”plan has X tasks — exceeds the per-goal task cap””Symptom: a CRITICAL ticket fires when the daemon claims a plan; the body cites _PLAN_HARD_CAP.
Cause: the planner emitted more than 6 tasks for one sub-objective. The hard cap is a guardrail; plans wanting more raise _PlanError and route to revise-major.
Fix: split the sub-objective. If the plan was emitted by Leader and you want to fix it once, edit the plan body to break the offending sub-objective into two narrower ones and re-approve. If Leader is consistently emitting over-scoped plans, the project’s deliverable shape is production-scale — see Example: production-scale Phase 1.
”Engine calibration: ! Multi-phase / long-running work — NOT yet supported”
Section titled “”Engine calibration: ! Multi-phase / long-running work — NOT yet supported””Symptom: modulatio doctor shows this line in its calibration banner, you’re trying to ship a 200-page novel.
Cause: Modulatio is honest — multi-phase / long-running work is later-release territory.
Fix: ship Phase 1 only via the production-scale shape. See Example: production-scale Phase 1. Queue Phases 2+ for a later release (Roadmap).
Diagnostic commands
Section titled “Diagnostic commands”When opening an issue or asking for help, include the output of:
modulatio --versionmodulatio doctormodulatio models listtail -50 ~/.config/modulatio/daemon.logtail -50 <vault>/.usage.jsonlThese five outputs cover ~90% of debugging needs.
When the docs are wrong
Section titled “When the docs are wrong”If you find a doc that’s incorrect, outdated, or unclear: open an issue or PR against the repo. Docs accuracy matters more than docs polish — fixing a wrong instruction beats writing a new section.