Skip to content

opencode run hangs forever with OpenAI-compatible local provider (DMR + Qwen3) even though direct curl works #12893

@ch1ch0-FOSS

Description

@ch1ch0-FOSS

Description

Summary

opencode run and the TUI hang indefinitely when using an OpenAI-compatible local provider (DMR + Qwen3) even though:

  • /v1/models works
  • /v1/chat/completions works from the same client machine
  • OpenCode sees and lists the models

After provider init, there are no HTTP logs, no errors, and no response until I Ctrl‑C. This makes it impossible to use local models from the TUI or CLI, even though the backend is healthy.


Environment

  • Client: ThinkPad T480 (x86_64)
  • Local model host: srv-m1m (Apple M1, Fedora Asahi)
  • OpenCode version: 1.1.53
  • Provider backend: DMR (OpenAI-compatible HTTP API)
  • Models: Qwen3 0.6B, 4B, 8B GGUF exposed via DMR
  • Network: T480 → srv-m1m over Tailscale (IP 100.104.206.96), no firewall issues

Provider configuration

Global ~/.config/opencode/opencode.json (simplified):

{
  "$schema": "https://opencode.ai/config.json",
  "provider": {
    "srv-m1m-dmr": {
      "name": "srv-m1m DMR Service Hub",
      "npm": "@ai-sdk/openai-compatible",
      "options": {
        "baseURL": "http://100.104.206.96:12434/v1",
        "timeout": 300000
      },
      "models": {
        "docker.io/ai/qwen3:8B-Q4_K_M": {
          "name": "Qwen3 8B Infrastructure",
          "limit": { "context": 32768, "output": 8192 }
        },
        "docker.io/ai/qwen3:4B-UD-Q4_K_XL": {
          "name": "Qwen3 4B Coding",
          "limit": { "context": 32768, "output": 4096 }
        },
        "docker.io/ai/qwen3:0.6B-Q4_0": {
          "name": "Qwen3 0.6B Systems",
          "limit": { "context": 4096, "output": 1024 }
        }
      }
    },
    "perplexity": {
      "name": "Perplexity Sonar Research",
      "npm": "@ai-sdk/openai-compatible",
      "options": {
        "baseURL": "https://api.perplexity.ai",
        "apiKey": "${PERPLEXITY_API_KEY}",
        "timeout": 120000
      },
      "models": {
        "sonar-pro": {
          "name": "Sonar Pro Research",
          "limit": { "context": 128000, "output": 4096 }
        }
      }
    }
  },
  "model": "srv-m1m-dmr/docker.io/ai/qwen3:8B-Q4_K_M",
  "small_model": "srv-m1m-dmr/docker.io/ai/qwen3:4B-UD-Q4_K_XL"
}

opencode models shows:

opencode/big-pickle
opencode/gpt-5-nano
opencode/kimi-k2.5-free
opencode/minimax-m2.1-free
opencode/trinity-large-preview-free
perplexity/sonar
perplexity/sonar-pro
perplexity/sonar-reasoning-pro
srv-m1m-dmr/docker.io/ai/qwen3:0.6B-Q4_0
srv-m1m-dmr/docker.io/ai/qwen3:4B-UD-Q4_K_XL
srv-m1m-dmr/docker.io/ai/qwen3:8B-Q4_K_M

So OpenCode is definitely loading the provider and models.


Backend health checks

On srv-m1m (same host as DMR):

curl -sS http://127.0.0.1:12434/v1/models

Output:

{"object":"list","data":[
  {"id":"docker.io/ai/qwen3:4B-UD-Q4_K_XL","object":"model","created":1761733632,"owned_by":"docker"},
  {"id":"docker.io/ai/qwen3:0.6B-Q4_0","object":"model","created":1746025981,"owned_by":"docker"},
  {"id":"docker.io/ai/qwen3:8B-Q4_K_M","object":"model","created":1746022478,"owned_by":"docker"}
]}

Direct chat test on srv-m1m:

curl -sS http://127.0.0.1:12434/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "docker.io/ai/qwen3:8B-Q4_K_M",
    "messages": [{"role": "user","content": "Say hello from qwen"}],
    "max_tokens": 32,
    "stream": false
  }'

Returns a valid chat.completion JSON with timings and usage.

From the ThinkPad T480 (same machine that runs OpenCode):

curl -sS http://100.104.206.96:12434/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "docker.io/ai/qwen3:8B-Q4_K_M",
    "messages": [{"role": "user","content": "Say hello from qwen (t480 direct)"}],
    "max_tokens": 32,
    "stream": false
  }'

Also returns a valid completion quickly (a few seconds). So the OpenAI-compatible backend is reachable and healthy from the client.


Reproduction steps

1. TUI

OPENCODE_LOG_LEVEL=DEBUG opencode --print-logs
  • TUI starts, logs show config loading and provider init.
  • In the TUI I select srv-m1m-dmr/docker.io/ai/qwen3:8B-Q4_K_M or 4B-UD-Q4_K_XL and send a short message like hello.
  • Result: spinner for several minutes, no response; no HTTP request logs for the provider appear.

2. CLI (run)

OPENCODE_LOG_LEVEL=DEBUG opencode run \
  --print-logs \
  --model srv-m1m-dmr/docker.io/ai/qwen3:4B-UD-Q4_K_XL \
  "respond with just: OK"

or (to try to bypass agents):

OPENCODE_CONFIG=$HOME/.config/opencode/opencode-test.json \
OPENCODE_LOG_LEVEL=DEBUG \
opencode run \
  --print-logs \
  --agent none \
  --model srv-m1m-dmr/docker.io/ai/qwen3:4B-UD-Q4_K_XL \
  "respond with just: OK"

Result: opencode run prints the initial prompt line and then hangs indefinitely (3–5 minutes until I Ctrl‑C) with no provider error and no HTTP call logged, even though the same model and endpoint work via curl.


Relevant log excerpt

From a run with --print-logs (abbreviated):

OPENCODE_CONFIG=$HOME/.config/opencode/opencode-test.json \
OPENCODE_LOG_LEVEL=DEBUG \
opencode run \
  --print-logs \
  --agent none \
  --model srv-m1m-dmr/docker.io/ai/qwen3:4B-UD-Q4_K_XL \
  "respond with just: OK"

INFO  ... service=default version=1.1.53 args=["run","--print-logs","--agent","none","--model","srv-m1m-dmr/docker.io/ai/qwen3:4B-UD-Q4_K_XL","respond with just: OK"] opencode
INFO  ... service=config path=/home/ch1ch0/.config/opencode/config.json loading
INFO  ... service=config path=/home/ch1ch0/.config/opencode/opencode.json loading
INFO  ... service=config path=/home/ch1ch0/.config/opencode/opencode.jsonc loading
INFO  ... service=config path=/home/ch1ch0/.config/opencode/opencode-test.json loading
INFO  ... service=config path=/home/ch1ch0/.opencode/opencode.jsonc loading
INFO  ... service=config path=/home/ch1ch0/.opencode/opencode.json loading
...
!  agent "none" not found. Falling back to default agent
...
INFO  ... service=server method=POST path=/session request
INFO  ... service=session id=ses_3baf812abffe9Dsmv66gA1g1Gn ... created
INFO  ... service=server method=POST path=/session/ses_3baf812abffe9Dsmv66gA1g1Gn/message request
INFO  ... service=provider status=started state
INFO  ... service=provider init
INFO  ... service=bus type=session.status publishing
INFO  ... service=session.prompt step=0 sessionID=ses_3baf812abffe9Dsmv66gA1g1Gn loop

After service=provider init there are no logs showing an outbound call to srv-m1m-dmr, no HTTP status, and no error. The process just sits there until I interrupt it.


What I expected

Given that:

  • The provider uses @ai-sdk/openai-compatible with a valid baseURL pointing at a healthy OpenAI-style backend, and
  • The same endpoint/model works from the same host via curl,

I expected:

  • opencode run and the TUI to send a POST /v1/chat/completions (or equivalent) to srv-m1m-dmr and either stream the response or show a clear error if something is wrong.
  • At minimum, a logged HTTP request and any resulting 4xx/5xx or timeout.

Instead, there is no HTTP log at all after provider init, and the CLI/TUI hang indefinitely.


Questions

  • Is this a known limitation/bug with local OpenAI-compatible providers (@ai-sdk/openai-compatible) that sit behind Tailscale, or with DMR specifically?
  • Is there a way to enable more verbose provider-level HTTP logging so we can see what OpenCode is trying to send?
  • Are there any constraints on model IDs (e.g., docker.io/ai/qwen3:8B-Q4_K_M) that could cause the provider to silently fail before making an HTTP call?

Happy to provide more complete logs or run a debug build if that helps. The main goal is to use OpenCode TUI with a local Qwen3 provider on an ARM64 Fedora Asahi host without relying on external SaaS.

Plugins

none - trying to use opencode in alignment with offical docs

OpenCode version

1.1.53

Steps to reproduce

No response

Screenshot and/or share link

No response

Operating System

fedora 43 server on Thinkpad t480 & Fedora Asahi server on M1 mac mini

Terminal

foot

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions