Skip to content

ECONNRESET with zai-coding-plan provider (api.z.ai) #15350

Closed as not planned
Closed as not planned

Description

@gletushov

Summary

Requests to Z.AI API (api.z.ai) fail with ECONNRESET after ~40-100 seconds when using the zai-coding-plan provider. The same API works correctly via curl and in other tools (e.g., OpenClaw via VPS proxy).

Environment

  • OpenCode: v1.2.15
  • Platform: macOS (arm64)
  • Provider: zai-coding-plan
  • Model: glm-5
  • Endpoint: https://api.z.ai/api/coding/paas/v4/chat/completions

Error Details

From ~/Library/Logs/ai.opencode.desktop/opencode-desktop_*.log:

ERROR service=llm providerID=zai-coding-plan modelID=glm-5 sessionID=ses_xxx small=false agent=build mode=primary 
error={"error":{"code":"ECONNRESET","path":"https://api.z.ai/api/coding/paas/v4/chat/completions","errno":0}} stream error

Timing pattern of failures (from logs):

  • Most failures occur after 39-100 seconds
  • Some as long as 1000+ seconds
  • 0 successful requests logged (101 ECONNRESET errors in one session)

Reproduction

  1. Configure zai-coding-plan provider with a valid API key via opencode auth login
  2. Select glm-5 model
  3. Send any prompt
  4. After ~40-100 seconds: ECONNRESET error

Verification that API works

Direct curl requests work fine:

curl -X POST "https://api.z.ai/api/coding/paas/v4/chat/completions" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <key>" \
  -d '{"model":"glm-5","messages":[{"role":"user","content":"hi"}],"stream":true}'
# Returns streaming response successfully

Same API also works when routed through a VPS proxy (tested with OpenClaw which proxies through a France VPS).

Analysis

The issue appears to be with Bun's HTTP client in the OpenCode sidecar:

  1. Bun's connection pooling: Bun aggressively reuses HTTP connections (keep-alive)
  2. Z.AI's idle timeout: Server likely closes idle connections after 30-60 seconds
  3. Race condition: When Bun tries to reuse a connection that the server has already closed → ECONNRESET

The sidecar process (opencode-cli serve) makes the actual API calls:

/Applications/OpenCode.app/Contents/MacOS/opencode-cli --print-logs --log-level WARN serve --hostname 127.0.0.1 --port XXXXX

Suggested Fix

  1. Disable keep-alive for Z.AI endpoints, or
  2. Add retry logic with fresh connection on ECONNRESET, or
  3. Reduce connection pool lifetime for streaming endpoints

Workaround Attempts

  • Setting HTTPS_PROXY environment variable: doesn't help (sidecar is separate process)
  • Bun config (~/.bunfig.toml): OpenCode binary appears to ignore it
  • VPN: issue persists regardless of network route

Related

Activity

  1. github-actions commented on Feb 27, 2026

    @github-actions
    Contributor

    This issue might be a duplicate of existing issues. Please check:

  2. added
    coreAnything pertaining to core functionality of the application (opencode server stuff)
    on Feb 27, 2026
  3. assigned and unassigned on Apr 26, 2026
  4. removed
    coreAnything pertaining to core functionality of the application (opencode server stuff)
    on May 3, 2026
  5. lele872 commented on May 31, 2026

    @lele872

    Confirming this issue persists on v1.14.50 (latest) with the same zai-coding-plan provider.

    Environment:

    • OpenCode: v1.14.50 (desktop app on macOS, arm64)
    • Provider: zai-coding-plan
    • Model: glm-5.1
    • Platform: macOS (Mac Studio, Apple Silicon)

    What I am seeing:

    The error appears intermittently in the desktop app UI as:

    Cannot connect to API: The socket connection was closed unexpectedly. For more i...
    retrying in 8s - attempt #4
    

    The retry logic kicks in and eventually recovers, but the user experience is poor — especially during long agent runs where this can happen multiple times per session. The error is not consistent; some requests succeed while others fail after ~30-60 seconds.

    Verification that the API itself works fine:

    Direct curl requests to api.z.ai work reliably with no disconnections:

    curl -s -m 10 -o /dev/null -w "HTTP: %{http_code}, Time: %{time_total}s\n" \
      https://open.bigmodel.cn/api/paas/v4/chat/completions
    # Returns: HTTP: 401, Time: 1.15s — connection is fine, 401 is expected without auth

    No proxy, no VPN, no firewall involved. The issue is isolated to the OpenCode sidecar.

    Root cause analysis (from source code investigation):

    I traced through the codebase and the flow is:

    1. The Bun runtime reuses HTTP keep-alive connections from its internal pool
    2. Z.AI's server closes idle connections after some timeout (~30-60s)
    3. When Bun tries to reuse a connection the server has already closed, it gets ECONNRESET
    4. In packages/llm/src/schema/errors.ts:118-128, TransportReason.retryable returns false, so the executor-level retry in packages/llm/src/route/executor.ts:342-353 does not retry the request with a fresh connection
    5. The error then bubbles up to packages/opencode/src/session/message-v2.ts:636-648, which correctly marks it as retryable at the session level — but by then the same stale connection may be reused again, causing repeated failures

    Suggested fix direction:

    The most effective fix would be to make TransportReason retryable in the executor (with the existing MAX_RETRIES = 2 cap), so ECONNRESET triggers an immediate retry with a new TCP connection before escalating to the session-level retry. This would catch the stale-connection case early and prevent the visible error loop.

    Alternatively, a custom fetch wrapper that sets Connection: close for providers known to have aggressive idle timeouts (or disables keep-alive pooling) would prevent the stale connection reuse entirely.

    Related issues and PRs I found:

    Happy to help test any fix or provide more logs if needed.

  6. github-actions commented on Jul 31, 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