1jehuang / 1jehuang/jcode

Swarm workers on Moonshot AI hang forever before the request is built (PROVIDER_CANONICAL_INPUT never logged)

Open
#718 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

autonomous: likely bug priority: medium triage: reproducible
Dominant language
Rust
Stars
19.9k
Forks
2.3k
Avg merge
2d 7h
Merged PRs (30d)
30

Description

Bug: Moonshot AI swarm workers hang forever before the request is built (PROVIDER_CANONICAL_INPUT never logged)

Version: v0.64.2 (6c6fbba1c), macOS aarch64
Provider: moonshot-ai (openai-compatible:moonshotai, https://api.moonshot.ai/v1), API key auth

Summary

Spawning a swarm worker on any moonshotai: model produces an agent that never
returns. It stays Activity: busy indefinitely (observed >3 min, and one earlier
worker sat unfinished for ~17 min). The journal only ever contains the initial
user message; no assistant message is ever appended.

The same models work correctly through the CLI on the same machine, same key,
same daemon. So this is specific to the swarm spawn path, not the provider,
the credential, or the model.

The exact fault line

A working swarm spawn logs PROVIDER_CANONICAL_INPUT and API stream opened
about 2 ms after API call starting. The Moonshot swarm spawn logs
API call starting and then nothing, ever.

Working swarm spawn (ollama:glm-5.2:cloud, answered in ~5 s):

18:39:27.250 [ses:session_butterfly_17|prv:OpenRouter|mod:glm] API call starting: 2 messages, 30 tools
18:39:27.252 [ses:session_butterfly_17|prv:OpenRouter|mod:glm] PROVIDER_CANONICAL_INPUT: provider=openai-compatible model=glm-5.2:cloud
18:39:27.252 [ses:session_butterfly_17|prv:OpenRouter|mod:glm] OpenRouter transport: HTTPS (SSE)
18:39:27.252 [ses:session_butterfly_17|prv:OpenRouter|mod:glm] API stream opened in 0.00s
18:39:27.252 [ses:session_butterfly_17|prv:OpenRouter|mod:glm] EVENT event=AGENT_PROVIDER_STREAM_LIFECYCLE ...
18:39:29.930 [ses:session_butterfly_17|prv:OpenRouter|mod:glm] EVENT event=AGENT_PROVIDER_STREAM_LIFECYCLE connection_type=https/sse ...

Hung Moonshot swarm spawn (moonshotai:kimi-k3) — complete log for the session,
nothing follows the last line:

19:20:24.969 EVENT event=SWARM_LIFECYCLE ... new_status=running old_status=ready phase=member_started
19:20:24.969 [ses:session_crab_1785626|prv:OpenRouter|mod:kimi] Created macOS sleep-prevention assertion while streaming (id=42902)
19:20:24.969 [ses:session_crab_1785626|prv:OpenRouter|mod:kimi] TURN_CANCEL_REGISTERED ... active_turns=1
19:20:24.969 [ses:session_crab_1785626|prv:OpenRouter|mod:kimi] messages_for_provider (compaction): returning 2 messages (user=2, assistant=0)
19:20:24.969 [ses:session_crab_1785626|prv:OpenRouter|mod:kimi] Locking tool list at 30 tools for cache stability
19:20:24.970 [ses:session_crab_1785626|prv:OpenRouter|mod:kimi] Prompt prefix estimate: total=19950 tokens (system=6540 tools=13410)
19:20:24.970 [ses:session_crab_1785626|prv:OpenRouter|mod:kimi] API call starting: 2 messages, 30 tools
<no further lines for this session, ever>

Event counts for the two sessions:

Session API call starting PROVIDER_CANONICAL_INPUT API stream opened STREAM_LIFECYCLE
butterfly (ollama, worked) 1 1 1 2+
crab (moonshot, hung) 1 0 0 0

So the worker wedges after the tool list is locked and the prompt is estimated,
but before the canonical provider request is emitted. No HTTP request appears to
be issued: lsof on the daemon showed no established connection to the Moonshot
Cloudflare range while a worker was hung.

Reproduction

swarm spawn label="repro" model="moonshotai:kimi-k3" prompt="Reply with exactly: REPRO. Then stop."

Worker stays busy forever. Same result for moonshotai:kimi-k2.7-code and
moonshotai:kimi-k2.6.

Interesting wrinkle: the very first Moonshot spawn of the session
(kimi-k2.7-code) succeeded and answered correctly in ~12 s. Every spawn after
that hung, including solo spawns with no other workers running, and including
kimi-k2.7-code again. That smells like one-shot state: a cached client,
connector, or semaphore for this provider that is initialised once and then not
reusable.

What I ruled out

  • Not the credential. Direct POST https://api.moonshot.ai/v1/chat/completions
    with the same key returns 200 in ~1.9 s.
  • Not rate limiting or quota. Direct API calls to kimi-k3 and
    kimi-k2.7-code succeeded immediately, both before and after reproducing the
    hang. No 429 anywhere in the logs.
  • Not payload size or tool schemas. Replaying the realistic agent payload
    (30 function tools + ~20k-token system prompt, stream: true) directly against
    the API returned 76 SSE chunks in 3.2 s.
  • Not the model. jcode run -p moonshot-ai -m kimi-k3 '...' completes
    normally, including a tool-calling prompt that reads a repo file and answers
    correctly. Those CLI sessions log AGENT_PROVIDER_STREAM_LIFECYCLE as expected.
  • Not the daemon being wedged. An ollama:glm-5.2:cloud worker spawned while
    a Moonshot worker was hung answered correctly in ~5 s.
  • Not model-name casing. A working Ollama spawn and a hung Moonshot spawn both
    render prv:OpenRouter in the session tag, so that difference is cosmetic.

Impact

Any swarm work routed to moonshotai: silently stalls. There is no error, no
timeout, and no failed status. The coordinator just sees a worker that is
permanently busy, so a run_plan or await_members on it would wait forever.
A hard failure would be much better than this.

Possibly related

#512 (non-Claude-route spawns die at boot). That looks different: those died
at boot with journals stuck at 4 K and reported failed. These get further,
building the prompt and locking tools, then hang as running and never settle.
Filing separately, happy to have it merged if maintainers see one root cause.

Suggested follow-up

  1. A timeout on the swarm worker path between API call starting and the first
    stream event, so this settles as failed rather than hanging forever.
  2. Check whether openai-compatible provider clients are cached per-provider in
    the spawn path in a way that only works once (consistent with first-spawn-works,
    all-later-spawns-hang).

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the swarm spawn path and trace the provider flow from API call starting to PROVIDER_CANONICAL_INPUT, using the supplied Moonshot reproduction and logs. Compare a first spawn with subsequent spawns and verify that hung workers fail with a timeout instead of remaining busy, while later Moonshot workers can complete.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
ai, backend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.