{"record":{"id":"506ad0f854f18bf3","repo":"zeroclaw-labs/zeroclaw","slug":"tracellmprovider-turn-current-requested-mor","errorCode":null,"errorMessage":"TraceLlmProvider({}): turn {current} requested more LLM responses than the trace provides for that turn","messagePattern":"TraceLlmProvider\\((.+?)\\): turn (.+?) requested more LLM responses than the trace provides for that turn","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/zeroclaw-eval/src/replay.rs","lineNumber":109,"sourceCode":"        _model: &str,\n        _temperature: Option<f64>,\n    ) -> anyhow::Result<String> {\n        // Not exercised by the agent loop (which uses `chat`); kept for trait completeness.\n        Ok(String::new())\n    }\n\n    async fn chat(\n        &self,\n        _request: ChatRequest<'_>,\n        _model: &str,\n        _temperature: Option<f64>,\n    ) -> anyhow::Result<ChatResponse> {\n        let step = {\n            let mut state = self.state.lock().unwrap();\n            let current = state.current;\n            match state.turns.get_mut(current).and_then(|q| q.pop_front()) {\n                Some(step) => step,\n                None => anyhow::bail!(\n                    \"TraceLlmProvider({}): turn {current} requested more LLM responses than the trace provides for that turn\",\n                    self.trace_name\n                ),\n            }\n        };\n        match step {\n            TraceResponse::Text {\n                content,\n                input_tokens,\n                output_tokens,\n            } => Ok(ChatResponse {\n                text: Some(content),\n                tool_calls: vec![],\n                usage: Some(TokenUsage {\n                    input_tokens: Some(input_tokens),\n                    output_tokens: Some(output_tokens),\n                    cached_input_tokens: None,\n                }),","sourceCodeStart":91,"sourceCodeEnd":127,"githubUrl":"https://github.com/zeroclaw-labs/zeroclaw/blob/88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc/crates/zeroclaw-eval/src/replay.rs#L91-L127","documentation":"`TraceLlmProvider::chat` pops the next scripted step for the current turn; when that turn's queue is empty it bails, naming the current turn index. The agent requested more LLM responses than the trace scripts for that turn — the fixture under-specifies the round-trips, often because the agent looped (e.g. retried after an unexpected tool result) and exhausted its scripted steps.","triggerScenarios":"An agent retry loop that makes one extra `chat()` call per turn; a trace turn array with too few entries; steps accidentally placed in the wrong turn index when splitting a recorded session.","commonSituations":"Hand-authoring traces with too few steps per turn; scripted tool outputs that do not match what the agent expects, forcing a clarifying round-trip; off-by-one errors at turn boundaries.","solutions":["Add the missing step(s) to the reported turn in the trace fixture so the queue covers every `chat()` call","If the extra call comes from an agent retry, fix the scripted tool output so the agent does not need to retry","Re-record the trace against the current agent behavior"],"exampleFix":"// before — turn 1 scripts 1 step but the agent calls chat() twice\n\"turns\": [[{\"text\":\"a\"}],[{\"text\":\"b\"}]]\n// after\n\"turns\": [[{\"text\":\"a\"}],[{\"text\":\"b\"},{\"text\":\"b-followup\"}]]","handlingStrategy":"validation","validationCode":"// Before running a case, assert every scripted tool call in the trace will\n// actually be requested: each tool_call step must correspond to a tool the\n// case's toolset exposes and the goal exercises.\nfn trace_tools_available(trace: &Trace, tools: &[ToolSpec]) -> anyhow::Result<()> {\n    for step in trace.turns.iter().flatten() {\n        if let Some(name) = step.tool_name() {\n            if !tools.iter().any(|t| t.name == name) {\n                anyhow::bail!(\"trace references tool '{name}' not in the case toolset\");\n            }\n        }\n    }\n    Ok(())\n}","typeGuard":null,"tryCatchPattern":"match provider.chat(...).await {\n    Err(e) if e.to_string().contains(\"more LLM responses than the trace\") => {\n        // under-scripted turn: report as fixture mismatch with the turn index\n        report.record_fixture_mismatch(case_name, e);\n    }\n    Err(e) => return Err(e),\n    Ok(resp) => resp,\n}","preventionTips":["Script deterministic tool outputs so the agent never needs an unplanned retry round-trip","After editing agent prompts or tool behavior, re-run and re-export the trace","Err on the side of extra terminal steps only when the agent flow guarantees them"],"tags":["eval","trace-replay","test-fixture","zeroclaw-eval"],"backgroundTag":"test-fixture-mismatch","analyzedSha":"88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc","analyzedAt":"2026-08-23T01:07:41.857Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}