Guides and How-toHow-to
Debug a stuck run
Read the transcript and runlog, find where a run stalled, and recover.
On this page
Canonical behavior lives in project-local sessions.db session_events; queryable runtime telemetry lives inhook_events. A run-bound events.jsonl is a portable projection. Correlate these withserve.log to distinguish a guarded termination from a genuinely blocked external call.
1. Query recent events
HookEventStore() resolves the current workspace database. Filter by session key and print the newest timeline in chronological order. Persisted payloads exclude raw prompts, user input, and tool inputs/results.
uv run python - <<'PY'
from core.observability.event_store import HookEventStore
store = HookEventStore()
try:
rows = store.read(limit=20, session_key="<session_key>")
for row in reversed(rows):
print(row.occurred_at, row.event, row.status, row.action)
finally:
store.close()
PY2. Check lifecycle pairs
- A missing
llm_call_endafterllm_call_startpoints at the model adapter boundary. - A missing
tool_exec_endaftertool_exec_startpoints at tool execution or process termination. status=blockedmeans a public hook or policy intentionally denied the operation.status=failedrecords failure on the canonical terminal row.
3. Correlate session history and daemon log
Inspect canonical sessions.db:session_events and, for run-bound work, its portable events.jsonl projection. A final tool.called without tool.completed, or a repeated identical call, should be matched by timestamp against~/.geode/logs/serve.log for tracebacks, timeouts, or credential failures.
4. Verify recovery
After fixing the cause, confirm the new timeline reaches the canonicalsession.ended event. Event rows are automatically pruned by retention class and a global cap; export evidence that needs longer artifact retention.
Moved from the GEODE repository’s documentation site. Source commit de077a4 · View the source on GitHub