{"record":{"id":"87e9dd4f039d9fd4","repo":"nikivdev/code","slug":"no-exchanges-found-in-session","errorCode":null,"errorMessage":"No exchanges found in session","messagePattern":"No exchanges found in session","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/ai.rs","lineNumber":1934,"sourceCode":"        context.push_str(\"\\n\\n\");\n        context.push_str(\"A: \");\n        context.push_str(&truncate_message(assistant_msg, MAX_MSG_CHARS));\n        context.push_str(\"\\n\\n\");\n    }\n\n    while context.ends_with('\\n') {\n        context.pop();\n    }\n    context.push('\\n');\n\n    Ok((context, last_ts))\n}\n\nfn read_codex_last_context(session_file: &PathBuf, count: usize) -> Result<String> {\n    let (exchanges, _last_ts) = read_codex_exchanges(session_file, None, None)?;\n\n    if exchanges.is_empty() {\n        bail!(\"No exchanges found in session\");\n    }\n\n    let start = exchanges.len().saturating_sub(count);\n    let last_exchanges = &exchanges[start..];\n\n    let mut context = String::new();\n    for (user_msg, assistant_msg, _ts) in last_exchanges {\n        context.push_str(\"Human: \");\n        context.push_str(user_msg);\n        context.push_str(\"\\n\\n\");\n        context.push_str(\"Assistant: \");\n        context.push_str(assistant_msg);\n        context.push_str(\"\\n\\n\");\n    }\n\n    while context.ends_with('\\n') {\n        context.pop();\n    }","sourceCodeStart":1916,"sourceCodeEnd":1952,"githubUrl":"https://github.com/nikivdev/code/blob/a747e741ae92c09071d0ae946ab48488adcff1ce/src/ai.rs#L1916-L1952","documentation":"read_codex_last_context reads a Codex session file and, if the parsed exchange list is empty (no user/assistant exchanges recorded), bails with 'No exchanges found in session'. The library requires at least one exchange to build the last-N context string.","triggerScenarios":"Calling read_codex_last_context on a Codex session whose JSONL file parses to zero exchanges — e.g. an empty/new session, a file containing only metadata lines, or count requested from an empty history.","commonSituations":"Requesting last context immediately after starting a session with no messages; a corrupted or truncated session file where message lines failed to parse.","solutions":["Send at least one message in the session before requesting its last context.","Check the session .jsonl file contains valid Codex message entries.","Point the command at the correct session file (a different, active session)."],"exampleFix":"// before\nf codex context --session fresh-session  // no messages yet\n// after\nf codex \"say hi\" && f codex context --session fresh-session","handlingStrategy":"validation","validationCode":"// rust\nlet (exchanges, _) = read_codex_exchanges(file, None, None)?;\nif exchanges.is_empty() { eprintln!(\"session has no exchanges yet\"); return; }","typeGuard":"fn has_exchanges(file: &PathBuf) -> bool {\n    read_codex_exchanges(file, None, None).map(|(e, _)| !e.is_empty()).unwrap_or(false)\n}","tryCatchPattern":"// rust\nmatch read_codex_last_context(&file, n) {\n    Err(e) if e.to_string() == \"No exchanges found in session\" => {\n        eprintln!(\"Send a message first; session is empty.\");\n    }\n    Err(e) => return Err(e),\n    Ok(ctx) => ctx,\n}","preventionTips":["Only request context after at least one exchange exists.","Validate the session file parses before depending on it.","Check file size/content of the .jsonl for empty sessions."],"tags":["empty-session","codex","sessions","parsing"],"backgroundTag":"no-exchanges-in-session","analyzedSha":"a747e741ae92c09071d0ae946ab48488adcff1ce","analyzedAt":"2026-09-01T22:43:55.719Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}