`jcode run` silently ignores JCODE_NAMED_PROVIDER_PROFILE and answers from the cloud default
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 19.9k
- Forks
- 2.3k
- Avg merge
- 2d 7h
- Merged PRs (30d)
- 30
Description
Source commit: 008abc44b1653efa65ccf98acb3b7236ce8507e6 (upstream master, chore(release): prepare v0.81.3)
Binary identity: jcode v0.81.5-dev (422da2bc0), SHA-256 ff2639739dc8b71c591cca8e02a3fb79255ef340bd7ce80bbb621ec9f9275ec8
Platform: macOS 26.6.2, Darwin 25.6.0, arm64, Apple M3 Pro
Local-build disclosure: the tested binary carries two local commits ahead of
008abc44b. Only one touches provider code, 422da2bc0, which adds a single
refresh_prompt_skills_snapshot() call in set_working_dir. It does not read,
set, or route on JCODE_NAMED_PROVIDER_PROFILE. The defect is in the
OpenAI-compatible provider path, which those commits do not modify.
Summary
With JCODE_NAMED_PROVIDER_PROFILE=<name> set, jcode run -m <model> does not
route to the named profile. It answers from the configured cloud default while
appearing to succeed.
The failure is silent. A deliberately nonexistent model id returns a confident
answer and exit code 0, and the local server records no corresponding request.
This is not a request for the environment variable to be supported. It is a
report that it is honored on some paths and ignored on this one, so a user who
sets it gets a plausible answer from the wrong model instead of an error.
Partial honoring is worse than no support, because the result is confidently
wrong rather than obviously broken.
Severity is raised by the observed consequence: this produced a false
verification claim in a downstream repository that was committed before the
routing was checked against server logs.
Reproduction
Any configured OpenAI-compatible named profile reproduces this. The profile used
here points at a local mlx-serve instance on 127.0.0.1:11234.
# ~/.jcode/config.toml
[providers.mlx-serve]
provider_type = "openai-compatible"
base_url = "http://127.0.0.1:11234/v1"
Case A — environment variable, nonexistent model (the defect)
JCODE_NAMED_PROVIDER_PROFILE=mlx-serve \
jcode run -m "mlx-community/DOES-NOT-EXIST-9999" "Reply with exactly: ok"
Observed:
ok
[Tokens] upload: 11593 download: 5 cache_read: 0 cache_write: 0
exit=0
The model id does not exist on any server. The answer came from the cloud
default. The mlx-serve access log records no request for this call.
Case B — supported flag, identical model id (correct behavior)
jcode run --provider-profile mlx-serve \
-m "mlx-community/DOES-NOT-EXIST-9999" "Reply with exactly: ok"
Observed:
endpoint: http://127.0.0.1:11234/v1/chat/completions
model: mlx-community/DOES-NOT-EXIST-9999
auth: local endpoint (no auth)
status: 503 Service Unavailable
exit=1
This is the desired behavior and the contrast that makes the defect clear: the
same input either fails loudly with the endpoint named, or succeeds silently
from the wrong provider, depending only on how the profile was selected.
A gibberish profile name in Case A behaves identically to a valid one, which
confirms the variable is not consulted on this path.
Root cause
JCODE_NAMED_PROVIDER_PROFILE is read across the codebase, but not once in
the OpenAI-compatible provider crates:
$ grep -rn 'JCODE_NAMED_PROVIDER_PROFILE' crates/jcode-provider-openai-runtime/ crates/jcode-provider-openai/ | wc -l
0
The Anthropic-compatible runtime implements exactly the missing behavior, in
crates/jcode-provider-anthropic-runtime/src/lib.rs:135:
fn active_anthropic_profile_models() -> Option<Vec<String>> {
let Ok(profile_name) = std::env::var("JCODE_NAMED_PROVIDER_PROFILE") else {
return None;
};
let profile = jcode_base::config::config().providers.get(&profile_name)?;
if !matches!(
profile.provider_type,
jcode_base::config::NamedProviderType::AnthropicCompatible
) {
return None;
}
// ...
}
crates/jcode-provider-openrouter-runtime/src/lib.rs:337 and
crates/jcode-base/src/provider/startup.rs also consult the variable. The
OpenAI-compatible path is the asymmetry.
Expected behavior
Either of these resolves the report; the choice is a maintainer design decision:
- Honor it. The OpenAI-compatible path resolves
JCODE_NAMED_PROVIDER_PROFILEthe way the Anthropic path already does, so
both selection mechanisms agree. - Reject it. If
--provider-profileis intended to be the only supported
selector for this path, then setting the variable without the flag should
fail with a message naming the supported flag, rather than falling back.
What should not remain is the current third option, where the variable is
accepted, ignored, and answered from a different provider.
Relationship to existing issues
- #712 (closed) is adjacent but distinct. There,
auth-testactively
clearedJCODE_NAMED_PROVIDER_PROFILEvia
force_apply_openai_compatible_profile_env, so the probe evaluated the wrong
target. Here,runnever reads the variable on the OpenAI-compatible path at
all. The shared theme is that profile selection is not uniform across
commands, and #712's fix did not generalize. - No open issue was found for this behavior. Searched
1jehuang/jcodefor
JCODE_NAMED_PROVIDER_PROFILE,run silently ignores profile, and
provider-doctoron 2026-08-31.
Downstream mitigation already applied
Recorded here so the maintainer can see this is a report, not a support request.
The affected downstream repository has retracted the false verification claim,
documented --provider-profile as the only supported invocation, and added a
regression test asserting that an unknown local model exits nonzero. That test
was confirmed to fail when the defect is reintroduced, not merely to pass today.
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.
Research direction
Run the two reproduction commands and compare the local server logs. Read crates/jcode-provider-anthropic-runtime/src/lib.rs:135, then inspect the OpenAI-compatible runtime crates and crates/jcode-base/src/provider/startup.rs for profile selection. Done means the environment-variable path either routes correctly or fails explicitly, with regression coverage for an unknown model.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- api, cli
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 52/100