Follow-ups from #941: two dispatch_name call sites, silent MCP name collisions, and complete_simple still dropping in-band errors
Nobody has claimed this yet.
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 30/100
Research direction
Start with src/cli/commands.rs:2549, crates/jcode-app-core/src/server/debug_command_exec.rs:327, Registry::register, create_mcp_tools, and complete_simple. Review the two named branches and the existing dispatch-name and stream-event tests before running the relevant crate checks. Done means normalized call sites agree with registration, collisions are diagnosed, and in-band stream errors no longer produce an empty successful response.
Written by the indexing model from the issue text.
Description
Three loose ends from #941 (which closed #936 and #937). All three are still present on master at c4cdc67. Filing as one issue since both source threads are now closed.
Branches, since PR creation is restricted to collaborators here:
fix/mcp-dispatch-name-call-sites— compare (items 1 and 2)fix/complete-simple-inband-errors— compare (item 3)
1. Two call sites still build the dispatch name by hand
dispatch_name normalizes - to _ in both segments, which the test in #941 pins (hyphenated-server -> mcp__hyphenated_server__). Two places still use the old format! and so no longer match what is registered.
src/cli/commands.rs:2549 — the cold-cache MCP startup wait:
let prefix = format!("mcp__{}__", server);
names.iter().any(|name| name.starts_with(&prefix))
For a server named my-server, registered tools are mcp__my_server__*, so covered never becomes true. The loop cannot detect readiness, burns the full budget, and then logs
jcode run: timed out waiting for cold-cache MCP server(s); their tools may be missing from this run
for tools that did in fact register. Silent latency plus a misleading warning.
crates/jcode-app-core/src/server/debug_command_exec.rs:327 — mcp:call:<server>:<tool>:
let tool_name = format!("mcp__{}__{}", server, tool);
Misses for a hyphen in either segment, which is the exact case #941 set out to fix.
Both are one-line swaps to dispatch_name. I also added a test pinning dispatch_name(server, "") against the full name, so a prefix scan cannot drift from the registered form again.
2. Dispatch-name collisions are silent
Because normalization is many-to-one, two distinct remote tools can collapse onto one dispatch name:
- one server exposing both
query-docsandquery_docs - two servers named
a-banda_b
Registry::register is tools.insert(name, tool), so the second registration silently replaces the first. The losing tool stays listed by mcp list but is not the tool that runs — a wrong-tool-executes failure with no diagnostic.
Rare, but bad enough to be worth surfacing. My branch detects duplicates in create_mcp_tools and logs a warning naming the collision. It deliberately does not rename, since the registered name is what maps back to the server's real tool; the point is to make the conflict visible, not to guess a winner.
3. complete_simple still drops in-band stream errors
This is the root cause behind #937's empty smoke output:, and it is unchanged:
match event {
Ok(StreamEvent::TextDelta(text)) => result.push_str(&text),
Ok(_) => {} // <- StreamEvent::Error lands here
Err(err) => return Err(err),
}
#941 fixed the Grok runtime to send Err instead, which resolves that report. But the in-band variant is still a legal way to report a failed turn, and other runtimes still use it. Concretely, jcode-provider-claude-cli-runtime converts to Err only when is_retryable_error matches and no output has been seen yet; anything outside that set, such as a stream-event parse failure from handle_output, is forwarded as Ok(StreamEvent::Error) and reaches this same path. Result: Ok(""), and the caller reports "response did not contain X" with nothing after it.
The current contract is effectively "return Err, and also never use the error variant if a caller might be complete_simple", which is easy to violate silently and gives no compile-time signal. Handling the variant here makes the guarantee hold whichever convention a runtime picks. Partial text is kept as evidence of how far the turn got.
Verification. cargo check passes for jcode-base --lib, jcode-app-core --lib, jcode --lib --bins, and jcode-provider-core; cargo fmt clean on all touched crates. I could not run the test binaries for these crates on this machine — security software deletes freshly linked executables on launch (Access is denied, os error 5), and the jcode-base test build exceeds my timeout — so the 2 tests added compile but I have not watched them pass. Flagging that rather than implying otherwise; CI will confirm.
Happy to split this into three separate issues if you would rather track them independently.
- Dominant language
- Rust
- Stars
- 19.9k
- Forks
- 2.3k
- Avg merge
- 2d 7h
- Merged PRs (30d)
- 30
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from 1jehuang/jcode
-
OrcaRouter is in the login catalog but has no ProviderChoice, so it can't be selected explicitly Open
Difficulty 2/5 1-3 hours Newbie friendliness 90/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 92/100
-
Session::save() skips untouched sessions, so is_debug and canary never persist (4 failing tests) Open
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
-
area: providers autonomous: clear bug triage: reproducible
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
-
area: providers autonomous: no bug triage: needs-decision
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 86/100
kwakseongjae/auto-hwp#319 ·
-
area:cli bug filter-quality good first issue priority:medium
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
-
Difficulty 1/5 Under an hour Newbie friendliness 72/100
bevyengine/bevy#25861 ·
-
comp-datalake
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
ClickHouse/ClickHouse#121222 ·
-
enhancement remote
Difficulty 2/5 1-3 hours Newbie friendliness 68/100