Skip to content

bug: Kimi/Moonshot provider crashes with 'undefined is not an object (evaluating $.annotations)' since v1.14.23 #26156

Closed as not planned

Description

@LURENYUANSHI

Bug Description

Since v1.14.23, using Kimi/Moonshot AI models (via moonshotai-cn provider, OpenAI-compatible protocol) causes all sessions to immediately crash with:

undefined is not an object (evaluating '$.annotations')

Followed by:

JSON Parse error: Unexpected EOF

Versions (binary search confirmed)

  • 1.14.22 ✅ works
  • 1.14.23 ❌ broken (first broken version)
  • 1.14.24 ~ 1.14.40 ❌ all broken

Root Cause Analysis

Bisected the commits between v1.14.22 and v1.14.23. The AI SDK version is unchanged ([email protected]) between both releases — the regression is in OpenCode's own code.

The most likely cause is PR #24005 (refactor(session): migrate session domain to Effect Schema), which migrated session/message schemas from zod to Effect Schema. Effect Schema's deserialization is stricter than zod — when Kimi/Moonshot's streaming response is missing a field (minified as $.annotations), zod silently ignores it but Effect Schema throws a TypeError.

Other PRs merged between v1.14.22 and v1.14.23 that touch related code:

The $.annotations is a minified variable name in the compiled binary, so the exact source location cannot be pinpointed externally. The error occurs immediately when the first streaming chunk arrives from the provider.

Reproduction

  1. Configure moonshotai-cn provider with a valid Moonshot API key
  2. Set model to moonshotai-cn/kimi-k2.6
  3. Open a new session and send any message
  4. Session immediately errors

Provider Config

{
  "model": "moonshotai-cn/kimi-k2.6",
  "provider": {
    "moonshotai-cn": {
      "npm": "@ai-sdk/openai-compatible",
      "name": "Moonshot AI (China)",
      "options": {
        "baseURL": "https://api.moonshot.cn/v1"
      }
    }
  }
}

Error Logs

Desktop Electron log:

[OpenCodeClient] OpenCode session.error properties={
  "sessionID": "ses_xxxxx",
  "error": {
    "name": "UnknownError",
    "data": {
      "message": "undefined is not an object (evaluating '$.annotations')"
    }
  }
}

Plugin log:

[session-recovery] Retry {"sessionID":"ses_xxxxx","attempt":1,"error":"undefined is not an object (evaluating '$.annotations')"}
[session-recovery] Recovery failed {"sessionID":"ses_xxxxx","error":"JSON Parse error: Unexpected EOF"}

Environment

  • OS: macOS (Darwin 24.5.0, arm64)
  • Node: v24.6.0
  • OpenCode installed via: npm install -g opencode-ai

Activity

  1. LURENYUANSHI commented on May 7, 2026

    @LURENYUANSHI
    Author

    And # 23244 pr

  2. superdav42 commented on May 11, 2026

    @superdav42

    Reproducing the same class of bug on OpenAI direct provider with openai/gpt-5.5 in OpenCode v1.14.48 (headless opencode run mode under the aidevops framework). Variable name in the TypeError is different (J.type vs $.annotations) because the minified binary names differ per build, but the failure shape and timing are identical to this issue, supporting the Effect Schema migration root-cause hypothesis in #24005.

    Error

    ERROR service=llm providerID=openai modelID=gpt-5.5 session.id=ses_1e717b7f0ffeH5ltHMkwPumHPg
      small=false agent=Build+ mode=primary error={"error":{}} stream error
    ERROR service=session.processor session.id=ses_1e717b7f0ffeH5ltHMkwPumHPg
      messageID=msg_e18e8ab0200110H3hpwjgZIy25
      error=undefined is not an object (evaluating 'J.type')
      stack=TypeError: undefined is not an object (evaluating 'J.type')
        at fetch (/$bunfs/root/chunk-n2wbvcp2.js:488:2526)
        at processTicksAndRejections (native:7:39)
    

    Wrapped stream error is {"error":{}} (empty inner) — same empty-Error wrapping pattern as #26129 / #21979.

    Crash sequence (from session ndjson)

    The crash fires immediately after a successful step-finish event with reason: "tool-calls":

    {"type":"step_finish","timestamp":1778534361830,"sessionID":"ses_1e717b7f0ffeH5ltHMkwPumHPg",
     "part":{"reason":"tool-calls","type":"step-finish",
             "tokens":{"total":29538,"input":755,"output":111,"reasoning":0,
                       "cache":{"write":0,"read":28672}}}}
    {"type":"error","timestamp":1778534362048,"sessionID":"ses_1e717b7f0ffeH5ltHMkwPumHPg",
     "error":{"name":"UnknownError",
              "data":{"message":"undefined is not an object (evaluating 'J.type')"}}}

    218 ms between events — consistent with the next streaming part arriving from the provider and failing Effect Schema deserialization. The minified J.type access strongly suggests the schema is unwrapping a streaming part object expecting .type to discriminate the union, and receiving undefined instead (likely an empty/null streaming delta after tool_calls).

    Reproduction

    Headless config: OpenAI direct provider, OAuth via aidevops account pool, gpt-5.5 model, tool-calling enabled (Build+ agent with TodoWrite, Bash, Edit, etc.). Crashes after 1–5 tool-call cycles. Observed 3/4 times in the last 24h on Ultimate-Multisite/ultimate-multisite headless workers; the 4th attempt succeeded on resume via next_action: "resume_session_with_completion_contract", suggesting the malformed chunk is transient/intermittent rather than deterministic for a given prompt.

    Same reasoning model class as #26107 (Free Models Thinking/Reasoning crashes) — possibly the empty/null delta corresponds to a reasoning step boundary in gpt-5.5's response stream.

    Side-signal (possibly unrelated)

    The sandbox boot also emits 4× schema rejections before the model crash:

    WARN service=server kind=Payload
      reason=Expected Auth, got {"type":"pending","refresh":"","access":"","expires":0}
      schema rejection
    

    This is the OAuth refresh path emitting a pending placeholder Auth object that the Effect Schema rejects. The session continues past this and only crashes later during streaming, so it may be cosmetic — but it confirms Effect Schema is now actively rejecting payloads that earlier schemas accepted.

    Environment

    • OpenCode v1.14.48 (Linux x86_64, Bun runtime)
    • OpenAI direct provider (not Copilot/Zen/openai-compatible — direct OAuth)
    • Model: openai/gpt-5.5
    • Mode: opencode run (headless, non-TUI)
    • Agent: Build+ with tool-calling
    • Same model on anthropic/claude-sonnet-4-6 direct provider: 5/5 success in same window, so the bug is isolated to the OpenAI streaming chunk parser, not the harness.

    Happy to provide full session ndjson, stderr captures, or run version bisection if useful.


    aidevops.sh v3.15.31 plugin for OpenCode v1.14.48 with claude-opus-4-7 spent 1h 7m and 74,137 tokens on this with the user in an interactive session.

  3. alex-pathcourse commented on May 12, 2026

    @alex-pathcourse
  4. hjhxtt commented on May 13, 2026

    @hjhxtt

    Confirming this also affects OpenRouter + GPT-5.5 Pro on macOS

    Same crash on a fresh session, immediately after first message.

    Environment

    • OpenCode: v1.14.28
    • OS: macOS Darwin 25.4.0 (arm64)
    • Node: v22.18.0, installed via npm i -g opencode-ai
    • Provider: openrouter (built-in)
    • Model: openrouter/openai/gpt-5.5-pro
    • MCP servers connected: chrome-devtools, memory, pencil

    Behavior

    • New session created → first prompt_async request → immediate crash
    • UI shows "UnknownError" banner; every retry creates a new session.error event
    • Switching model to other OpenAI/OpenRouter models (gpt-5, etc.) does not help
    • Confirmed by downgrading to v1.14.22: fully resolved, same config and same UI works on first try

    Log excerpt
    ```
    ERROR service=server sessionID=ses_xxxxx
    error=undefined is not an object (evaluating '$.annotations') prompt_async failed
    ```

    Stack frames identical to OP (`chunk-kprvzcvq.js:1107`, `~effect/Effect/successCont`, `runLoop`).

    So the breakage is not specific to Moonshot/`@ai-sdk/openai-compatible` — the built-in `openrouter` provider hits the exact same path. Anthropic direct (Claude Sonnet 4.6) works fine, matching the earlier comment.

    Happy to provide full session.error payload from `~/.local/share/opencode/log/` if useful.

  5. github-actions commented on Jul 13, 2026

    @github-actions
    Contributor

    To stay organized issues are automatically closed after 60 days of no activity. If the issue is still relevant please open a new one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

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