affaan-m/ECC · error · anyhow::Error
Session not found: {session_id}
Error message
Session not found: {session_id} What it means
The record_tool_call function looks up a session by ID in the state store to attach a tool-call log entry. If no session with that ID exists in the database, it bails. The session must exist because the tool-call event and the tool-call counter increment are both keyed on the session.
Source
Thrown at ecc2/src/session/manager.rs:1475
format!(
"Queued manual merge on {path}; paused later session {} until merge review against {}",
latest.session_id, other.session_id
),
),
}
}
pub fn record_tool_call(
db: &StateStore,
session_id: &str,
tool_name: &str,
input_summary: &str,
output_summary: &str,
duration_ms: u64,
) -> Result<ToolLogEntry> {
let session = db
.get_session(session_id)?
.ok_or_else(|| anyhow::anyhow!("Session not found: {session_id}"))?;
let event = ToolCallEvent::new(
session.id.clone(),
tool_name,
input_summary,
output_summary,
duration_ms,
);
let entry = log_tool_call(db, &event)?;
db.increment_tool_calls(&session.id)?;
Ok(entry)
}
pub fn query_tool_calls(
db: &StateStore,
session_id: &str,
page: u64,View on GitHub (pinned to 01e15490f0)
Solutions
- Verify the session exists with db.get_session(session_id) before calling record_tool_call
- Check that the session was not deleted by a concurrent delete_session call
- Ensure the DB path in cfg.db_path points to the correct state store file
- If logging tool calls for a session that may have been cleaned up, handle the NotFound case gracefully rather than propagating the error
Example fix
// before
let entry = record_tool_call(db, session_id, tool, input, output, duration)?;
// after
if db.get_session(session_id)?.is_none() {
tracing::warn!("session {session_id} no longer exists, skipping tool call log");
return Ok(Default::default());
}
let entry = record_tool_call(db, session_id, tool, input, output, duration)?; Defensive patterns
Strategy: validation
Validate before calling
if db.get_session(session_id)?.is_none() {
tracing::warn!("session {session_id} not found, skipping tool call recording");
return Ok(Default::default());
}
let entry = record_tool_call(db, session_id, tool_name, input, output, duration)?; Try / catch
match record_tool_call(db, session_id, tool, input, output, duration) {
Ok(entry) => Ok(entry),
Err(e) if e.to_string().contains("Session not found") => {
tracing::warn!("session {session_id} gone, tool call not recorded");
Ok(Default::default())
}
Err(e) => Err(e),
} Prevention
- Always verify session existence before recording tool calls from async/lazy contexts
- Avoid passing raw session IDs across process boundaries where deletion races exist
- Use a session registry that prevents deletion while tool calls are in flight
When it happens
Trigger: Calling record_tool_call(db, session_id, ...) with a session_id that db.get_session() cannot find — the session was never created, was already deleted, or the ID is misspelled.
Common situations: Session was deleted between spawn and tool-call logging. DB file was reset or corrupted. Passing a stale session ID from a previous run. Typo or truncated session ID.
Related errors
- Session not found: {id}
- Session {} has no attached worktree
- Session not found: {session_id}
- Unable to load issue #${issueNumber} from ${repo}
- Memory ${memoryId} was not found.
AI-assisted analysis of affaan-m/ECC@01e15490f0 (2026-08-13).
Data as JSON: /api/errors/3c4caef57cf3e3e8.
Report an issue: GitHub.