-
Notifications
You must be signed in to change notification settings - Fork 0
Troubleshooting
Symptom: The Mac locks up completely during the 5am launchd run. Forced reboot required. logs/cron.log shows the pipeline start and collection phase, then cuts off abruptly during Pass 1 — no error message, no Python traceback.
Root cause: Ollama uses Apple Metal for GPU inference. When invoked from a launchd background daemon, Metal access runs in a non-interactive GPU session context that differs from a normal user login session. This mismatch triggers a Metal/GPU driver kernel panic.
Resolution: Switch to Claude Code CLI as the LLM provider for all automated runs. Claude makes HTTPS calls to Anthropic's API — no Metal, no GPU, no kernel-level resources.
The current configuration already has this fix applied:
-
config/sources.yaml:llm.provider: claude -
scripts/com.flexrpl.signal.plist:SIGNAL_LLM_PROVIDER=claude -
scripts/run_and_publish.sh:export SIGNAL_LLM_PROVIDER="${SIGNAL_LLM_PROVIDER:-claude}"
Important: Do not change SIGNAL_LLM_PROVIDER to ollama in the plist or script. Use Ollama only for interactive manual runs from the terminal.
For the full investigation (system logs, panic file analysis, reboot confirmation via last reboot), see docs/troubleshooting-macos-crash.md in the repository.
Check it's loaded:
launchctl list | grep flexrplIf missing:
launchctl load ~/Library/LaunchAgents/com.flexrpl.signal.plistCheck the log:
cat logs/cron.logSchedule didn't update after editing the plist:
The active copy in ~/Library/LaunchAgents/ was not updated. Always run:
launchctl unload ~/Library/LaunchAgents/com.flexrpl.signal.plist
cp scripts/com.flexrpl.signal.plist ~/Library/LaunchAgents/
launchctl load ~/Library/LaunchAgents/com.flexrpl.signal.plistCannot reach Claude CLI:
which claude # should return /opt/homebrew/bin/claude
claude --version # should return 2.x.x (Claude Code)If missing:
npm install -g @anthropic-ai/claude-code
claude auth loginClaude CLI non-zero exit during Pass 1:
Claude rate-limited or returned an error. The pipeline logs the error and continues with the next article — it doesn't abort. Check logs/cron.log for the frequency of these errors.
Cannot reach Ollama:
ollama serve # start the server
ollama list # confirm qwen2.5:14b is presentModel not found:
ollama pull qwen2.5:14bNo articles collected. Check feeds / network.Run the smoke test to identify which feeds are failing:
python3 main.py --collect-onlyLook for ✗ <source name>: <error> lines in the output. Common causes:
- Source changed its RSS URL
- Network connectivity issue
- Source's RSS feed is temporarily down
LLM error: ...The LLM returned malformed JSON. _parse_json_response() tries several recovery strategies (strip markdown fences, regex search for JSON object) before returning None. When it returns None, the pass uses a safe fallback dict and continues.
This is non-deterministic — re-running the pipeline usually resolves it. If it happens consistently for the same cluster, the article content may be triggering unusual LLM output (e.g. articles with non-English characters, very short articles, or articles with unusual formatting).
Pass 5 uses a min(timeout * 3, 360) timeout (max 6 minutes). If it consistently times out:
-
Increase the timeout in
config/sources.yaml:claude: timeout: 240 # 4 minutes → Pass 5 gets up to 360s (capped)
-
Check if the prompt is hitting context window limits. The
story_analysesinput is capped at 6000 characters insynthesize_brief().
This means a run_id or cluster_id being written doesn't match an existing record in the parent table.
Most likely cause: signal.db was corrupted (e.g. by a mid-run crash).
Fix:
rm signal.db
python3 main.pyThe database is recreated automatically. All previous analysis is lost but the HTML reports in reports/ remain.
--no-venv skips venv setup and runs with the current Python interpreter directly. If that interpreter doesn't have the dependencies installed, you'll get ModuleNotFoundError.
The run_and_publish.sh script uses the venv Python explicitly:
PYTHON="$REPO/.venv/bin/python"
"$PYTHON" main.py --no-venvIf you deleted .venv, run without --no-venv once to recreate it:
python3 main.pyThe archive was not updated in the most recent commit. This happens if archive.html was not included in the git add.
Fix immediately:
git add archive.html
git commit -m "fix: update archive.html"
git push origin mainThe run_and_publish.sh script now explicitly stages archive.html on every run to prevent this.
The "◁ Home" button uses a relative path: href="../index.html". This works correctly when reports are served from reports/brief_*.html on GitHub Pages (parent directory is the repo root where index.html lives).
If viewing a report by opening the HTML file directly from the filesystem (file:///.../reports/brief_*.html), the relative path may not resolve correctly depending on your browser. Open it through a local server or directly via open from the terminal.
# Check for unexpected reboots
last reboot
# List system crash and panic logs
ls -lt /Library/Logs/DiagnosticReports/
# Check launchd events for the signal job
log show --predicate 'eventMessage CONTAINS "flexrpl"' --style compact
# Check system logs around a specific window
log show --start "YYYY-MM-DD HH:MM:00" --end "YYYY-MM-DD HH:MM:00" \
--predicate 'processImagePath contains "python" OR eventMessage contains "panic"' \
--style compact
# Check what caused a bash crash report
grep -o '"responsibleProc"[^,]*\|"coalitionName"[^,]*' \
~/Library/Logs/DiagnosticReports/bash-<timestamp>.ips
# Confirm Python process is running during a slow pass
ps aux | grep python | grep -v grep
# Confirm Claude subprocesses are spawning during Pass 1
ps aux | grep claude | grep -v grepSignal · Repository · fleXRPL · Daily political intelligence — powered by local AI