You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
0.49.23 (omp 18.12.6): prepared turn structure ... comparison=role refusal: dropping a tool call can leave two adjacent assistants, and omp's Anthropic Continue. repair row isn't modeled #789
On a resumed omp session (Anthropic Messages API, dispatch fence on, side_contexts=0), every turn is refused:
refused (provider request does not match this pass's managed dispatch (prepared turn structure);
row=22 expectedRows=611 actualRows=616 expectedRole=assistant actualRole=user
expectedCalls=1 actualCalls=0 expectedResults=0 actualResults=0 comparison=role)
Retrying never helps, because the wire always has exactly 5 more rows than the prepared structure.
Environment
@cortexkit/pi-magic-context 0.49.23
omp 18.12.6, provider api anthropic-messages (claude-sonnet-5-5)
Session of ~1,840 entries; it contains 95 todo tool calls
Cause (reproduced)
I reproduced it in an isolated HOME (copied context.db, fake Anthropic endpoint) and instrumented the copy so it dumps active.preparedStructure together with the actual payload at the fence:
MC's transform output keeps only 19 of the session's 95 todo tool calls. It removes the others together with their results.
Five assistant messages consisted of one short text block plus a single todo call (e.g. "Refreshing the todo list, dispatching next." + todo). With the call removed, each becomes a text-only assistant, and the next row in MC's output is also an assistant.
omp's Anthropic converter (@oh-my-pi/pi-aiproviders/anthropic.ts, the "Dropped empty user/developer turns can leave two assistant params adjacent" loop) repairs adjacent assistant params by inserting { role: "user", content: "Continue." } between them.
The prepared structure doesn't model that repair. The payload has a user "Continue." row at index 16, 181, 238, 312 and 426, which is 5 extra rows. The first one shifts the comparison so that it fails at row 22 with expectedRole=assistant actualRole=user.
Every pass reproduces it, since the adjacency is produced by MC's own output.
Suggested direction
Either of these would fix it:
When removing tool calls leaves an assistant message adjacent to another assistant, don't emit that shape: merge the two, drop the remnant, or keep the call. Or
Thanks for the careful reproduction. Dumping the prepared structure next to the actual payload made this quick to confirm.
Confirmed. When Magic Context removes an old tool call together with its result, an assistant message that held only short text and that call can end up directly before another assistant message. Oh My Pi's Anthropic converter then inserts a Continue. user message between the two adjacent assistants (providers/anthropic.ts, in the loop that repairs adjacent assistant params). Our check of the prepared turn structure doesn't expect that row, so every pass sees extra rows and refuses the turn.
We're working on a fix. The check will expect the Continue. row exactly where Oh My Pi inserts one, and keep refusing any other mismatch. I'll post here when it ships.
Fixed in 0.49.24. Thanks @TheOrdinaryWow for the report and the reproduction.
When dropping a tool call left two assistant messages next to each other, Oh My Pi inserts its Continue. repair message between them. Magic Context's request check now expects that message, so the turn is no longer refused with comparison=role.
Update the Pi package and restart Oh My Pi to pick it up.
Activity
magic-alfonso commentedon Oct 26, 2026
Thanks for the careful reproduction. Dumping the prepared structure next to the actual payload made this quick to confirm.
Confirmed. When Magic Context removes an old tool call together with its result, an assistant message that held only short text and that call can end up directly before another assistant message. Oh My Pi's Anthropic converter then inserts a
Continue.user message between the two adjacent assistants (providers/anthropic.ts, in the loop that repairs adjacent assistant params). Our check of the prepared turn structure doesn't expect that row, so every pass sees extra rows and refuses the turn.We're working on a fix. The check will expect the
Continue.row exactly where Oh My Pi inserts one, and keep refusing any other mismatch. I'll post here when it ships.magic-alfonso commentedon Oct 27, 2026
Fixed in 0.49.24. Thanks @TheOrdinaryWow for the report and the reproduction.
When dropping a tool call left two assistant messages next to each other, Oh My Pi inserts its
Continue.repair message between them. Magic Context's request check now expects that message, so the turn is no longer refused withcomparison=role.Update the Pi package and restart Oh My Pi to pick it up.