Summary
A swarm spawn payload that contains a valid prompt but also contains initial_message: "" silently discards the prompt. The worker is created without its task and may spend a long time reasoning before asking the coordinator what it was supposed to do.
I initially encountered this while testing a local Qwen model through vLLM and CLIProxyAPI/CloudCLIProxy. I suspected the model or proxy configuration first. After tracing the recorded spawn payload and Jcode's source, the missing initial task is reproducible entirely inside Jcode before the provider request is built.
This report is intentionally limited to prompt selection. It does not claim that the proxy/model's tool-calling configuration is otherwise perfect. There may still be independent provider issues, but they cannot explain this particular empty startup message.
Environment
- Installed Jcode:
v0.76.0 (bbef1f6a8)
- Current upstream checked at:
c4cdc67680e30a957dc86c68c955ea0605a316f3
- macOS
- Spawn mode observed: inline/headless worker
- Provider in the original observation: custom OpenAI-compatible CLIProxyAPI route to vLLM/Qwen
Reproduction
Send a spawn call with both fields, where initial_message is present but blank:
{
"action": "spawn",
"label": "local html executor",
"model": "cliproxyapi:local",
"prompt": "Create /Users/example/Desktop/page/index.html, then report completion.",
"initial_message": ""
}
This shape can occur when a caller/tool serializer emits optional string fields as empty strings while using the documented prompt field for the actual task.
Minimal unit-level reproduction
let input: CommunicateInput = serde_json::from_value(serde_json::json!({
"action": "spawn",
"initial_message": "",
"prompt": "preserve this task"
}))?;
assert_eq!(input.spawn_initial_message().as_deref(), Some("preserve this task"));
The assertion currently fails because the result is Some("").
Root cause
Current upstream code in crates/jcode-app-core/src/tool/communicate.rs:
fn spawn_initial_message(&self) -> Option<String> {
self.initial_message.clone().or_else(|| self.prompt.clone())
}
Option::or_else only falls back for None. Some("") is still Some, so the non-empty prompt is never considered. spawn_swarm_agent then receives the blank value and uses it as the startup message.
In the observed sessions, the recorded tool call visibly contained the full task in prompt and initial_message: "". Two fresh workers subsequently contacted the coordinator with variants of:
What's my task? I was spawned as "local html executor" but I don't have the task prompt or details.
This aligns exactly with the source behavior.
Expected behavior
Blank or whitespace-only aliases should be treated as absent:
- Prefer a nonblank
initial_message.
- Otherwise use a nonblank
prompt.
- Otherwise return
None.
Suggested fix
fn spawn_initial_message(&self) -> Option<String> {
self.initial_message
.as_ref()
.filter(|message| !message.trim().is_empty())
.cloned()
.or_else(|| {
self.prompt
.as_ref()
.filter(|prompt| !prompt.trim().is_empty())
.cloned()
})
}
I applied this locally and added a regression case to communicate_tests/input_format.rs. The targeted test passes:
running 1 test
test tool::communicate::tests::spawn_initial_message_accepts_prompt_alias_and_prefers_explicit_initial_message ... ok
test result: ok. 1 passed; 0 failed
Impact
- Spawned workers can lose their entire assignment while still receiving a valid label.
- The symptom can be misdiagnosed as model context loss, bad chat templates, or proxy/provider incompatibility.
- Reasoning models may consume substantial tokens while trying to recover the missing task.
- Follow-up DMs do not necessarily rescue a worker already stuck in a long generation.
Duplicate check
I searched open and closed issues for initial_message, swarm prompt, spawn prompt lost task, and related wording and did not find an existing report for this behavior.
Summary
A swarm spawn payload that contains a valid
promptbut also containsinitial_message: ""silently discards the prompt. The worker is created without its task and may spend a long time reasoning before asking the coordinator what it was supposed to do.I initially encountered this while testing a local Qwen model through vLLM and CLIProxyAPI/CloudCLIProxy. I suspected the model or proxy configuration first. After tracing the recorded spawn payload and Jcode's source, the missing initial task is reproducible entirely inside Jcode before the provider request is built.
This report is intentionally limited to prompt selection. It does not claim that the proxy/model's tool-calling configuration is otherwise perfect. There may still be independent provider issues, but they cannot explain this particular empty startup message.
Environment
v0.76.0 (bbef1f6a8)c4cdc67680e30a957dc86c68c955ea0605a316f3Reproduction
Send a spawn call with both fields, where
initial_messageis present but blank:{ "action": "spawn", "label": "local html executor", "model": "cliproxyapi:local", "prompt": "Create /Users/example/Desktop/page/index.html, then report completion.", "initial_message": "" }This shape can occur when a caller/tool serializer emits optional string fields as empty strings while using the documented
promptfield for the actual task.Minimal unit-level reproduction
The assertion currently fails because the result is
Some("").Root cause
Current upstream code in
crates/jcode-app-core/src/tool/communicate.rs:Option::or_elseonly falls back forNone.Some("")is stillSome, so the non-emptypromptis never considered.spawn_swarm_agentthen receives the blank value and uses it as the startup message.In the observed sessions, the recorded tool call visibly contained the full task in
promptandinitial_message: "". Two fresh workers subsequently contacted the coordinator with variants of:This aligns exactly with the source behavior.
Expected behavior
Blank or whitespace-only aliases should be treated as absent:
initial_message.prompt.None.Suggested fix
I applied this locally and added a regression case to
communicate_tests/input_format.rs. The targeted test passes:Impact
Duplicate check
I searched open and closed issues for
initial_message,swarm prompt,spawn prompt lost task, and related wording and did not find an existing report for this behavior.