Skip to content

Conversation resume causes Gemini API 400 error due to message history snipping; switching to GPT-5.4 leads to agent loop and rate limiting #84

Description

@wbszhu
 Description

 When resuming a long conversation in Pantheon Desktop, the backend encounters a fatal error loop that makes the chat completely unresponsive.
 Restarting the desktop app does not resolve the issue — the same conversation fails again upon resume. Three cascading issues were observed:

 1. Gemini API 400: Invalid turn ordering after history snipping — The snip_messages_to_budget token optimization drops messages from the
 conversation history to fit the context window. After snipping ~32 messages, the resulting history violates Gemini's turn-ordering constraint
 ("Please ensure that function call turn comes immediately after a user turn or after a function response turn."). All 4 retry attempts fail with the
  same error, crashing the conversation thread.
 2. Agent enters infinite "Think" loop on GPT-5.4 — After switching the model to codex/gpt-5.4 to work around the Gemini error, the Leader agent
 enters a degenerate loop: it repeatedly reads the same brain files (task.md, plan.md, report.md, etc.) and executes trivial python3 shell commands
 that only print "Think: analyzing..." without making any real progress. This burns through tokens and API calls rapidly.
 3. GPT-5.4 rate limited (429) after agent loop — The rapid-fire LLM calls from the agent loop quickly exhaust the rate limit. All 4 retry attempts
 return 429, crashing the conversation thread a second time.

 Additionally, the local NATS server experienced intermittent disconnections ("unexpected EOF" on port 4222) with ~20-second reconnection delays,
 which may have contributed to message delivery issues.

 Steps to Reproduce

 1. Have a long-running conversation with many tool calls (the affected chat had 224+ raw messages and ~87K estimated tokens)
 2. The conversation gets interrupted (e.g., by a previous crash or app restart)
 3. Send a message (e.g., "继续" / "continue") to resume the conversation
 4. The backend performs snip_messages_to_budget, dropping messages from history
 5. The snipped history results in invalid turn ordering for the Gemini API
 6. All retries fail → RuntimeError
 7. Switching to a different model (GPT-5.4) causes an agent loop → rate limiting → second RuntimeError

 Expected Behavior

 - The snip_messages_to_budget optimization should preserve valid turn ordering for all supported LLM providers (especially Gemini's strict
 function-call turn adjacency requirement)
 - The agent should not enter a degenerate loop that makes no progress while consuming API calls
 - If a conversation is in an unrecoverable state, the user should be informed with a clear error message and given the option to start a new
 conversation or reset the history

 Actual Behavior

 - The conversation becomes completely stuck — neither Gemini nor GPT-5.4 can process it
 - Restarting the desktop app does not help because the corrupted conversation history is persisted to disk (~/.pantheon/memory/<chat_id>.jsonl)
 - No user-facing error message is shown (the error is only visible in backend logs)

 Environment

 - App: Pantheon Desktop (macOS, /Applications/pantheon-desktop.app/)
 - Date: 2026-04-14
 - Models affected: gemini/gemini-3-flash-preview, codex/gpt-5.4
 - NATS: Local server on nats://localhost:4222
 - Chat ID: f021e04f-b8a0-4cc0-8c4f-621fbf360bc2

 Relevant Log Excerpts

 Gemini 400 error (first occurrence):
 2026-04-14 14:50:40.550 | ERROR | pantheon.utils.llm:acompletion:777 -
   [ACOMPLETION] ✗ Call failed | Model=gemini-3-flash-preview |
   Error=InternalServerError: Gemini API error 400: {
     "error": {
       "code": 400,
       "message": "Please ensure that function call turn comes immediately after a user turn or after a function response turn.",
       "status": "INVALID_ARGUMENT"
     }
   }

 Token optimization that likely caused it:
 2026-04-14 14:50:39.871 | INFO | pantheon.utils.token_optimization:snip_messages_to_budget:1058 -
   [token optimization] history snip freed ~3680 tokens (32 messages dropped)

 GPT-5.4 rate limit (all 4 attempts):
 2026-04-14 18:25:08.012 | ERROR | pantheon.utils.llm:acompletion:777 -
   [ACOMPLETION] ✗ Call failed | Model=gpt-5.4 | Error=RateLimitError: Codex rate limited (429)
 ...
 2026-04-14 18:25:14.860 | ERROR | pantheon.agent:_acompletion_with_models:1815 -
   Rate limit exceeded for codex/gpt-5.4 after retries: Codex rate limited (429)

 NATS disconnection:
 2026-04-14 18:41:21.762 | WARNING | pantheon.remote.backend.nats:_error_cb:206 -
   [NATS] Connection error: nats: unexpected EOF
 2026-04-14 18:41:21.764 | WARNING | pantheon.remote.backend.nats:_disconnected_cb:211 -
   [NATS] Disconnected from server

backend.log

Image

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions