Summary
Two bugs in NadirClaw's message processing break all multi-turn conversations that use tool calling (which is every OpenCode session).
Bug 1: Optimizer strips tool_calls and tool_call_id
optimize_messages() in nadirclaw/server.py (lines 1104-1107) converts all messages to plain {"role", "content"} dicts before processing:
raw_msgs = [
{"role": m.role, "content": m.text_content()}
for m in request.messages
]
This drops tool_calls from assistant messages and tool_call_id from tool messages. Bedrock/Mantle rejects the malformed conversation:
BadRequestError: missing field `tool_call_id` at line 1 column 19202
Fix: NADIRCLAW_OPTIMIZE=off in config (c37cad8)
Bug 2: content: null on tool-call-only assistant messages
In _stream_litellm() and _call_litellm(), the message content assignment:
text = message.text_content()
content = text if text else message.content
When an assistant message has only tool_calls (no text), text_content() returns "" (empty string). The falsy check if text treats "" as False, falling through to message.content which is None. Bedrock rejects content: null.
Fix: content = text if text is not None else message.content (sed patch in Dockerfile)
Impact
- Every multi-turn conversation with tool use fails
- All models in the fallback chain exhaust instantly (<2s total)
- Users see "All configured models are currently unavailable"
- Affects any client that sends tool_calls (OpenCode, Claude Code, Cursor, Continue)
Upstream
These are NadirClaw bugs. Should be reported to NadirRouter/NadirClaw.
Related
Summary
Two bugs in NadirClaw's message processing break all multi-turn conversations that use tool calling (which is every OpenCode session).
Bug 1: Optimizer strips
tool_callsandtool_call_idoptimize_messages()innadirclaw/server.py(lines 1104-1107) converts all messages to plain{"role", "content"}dicts before processing:This drops
tool_callsfrom assistant messages andtool_call_idfrom tool messages. Bedrock/Mantle rejects the malformed conversation:Fix:
NADIRCLAW_OPTIMIZE=offin config (c37cad8)Bug 2:
content: nullon tool-call-only assistant messagesIn
_stream_litellm()and_call_litellm(), the message content assignment:When an assistant message has only
tool_calls(no text),text_content()returns""(empty string). The falsy checkif texttreats""asFalse, falling through tomessage.contentwhich isNone. Bedrock rejectscontent: null.Fix:
content = text if text is not None else message.content(sed patch in Dockerfile)Impact
Upstream
These are NadirClaw bugs. Should be reported to NadirRouter/NadirClaw.
Related