xai-org/grok-build · error
set_client_name called more than once
Error message
set_client_name called more than once
What it means
set_client_name stores the process-level fallback ClientType (used for the User-Agent origin) in a OnceCell and .expect()s the set succeeds, so a second call in the same process panics with 'set_client_name called more than once'. The value is intentionally write-once per process.
Source
Thrown at crates/codegen/xai-grok-http/src/lib.rs:177
self.origin.product,
self.agent_product,
self.agent_version,
self.platform.os,
self.platform.arch,
),
}
}
}
fn agent_version() -> String {
xai_grok_version::VERSION.to_string()
}
/// Set the process-level fallback origin client type for `User-Agent`.
pub fn set_client_name(client_type: ClientType) {
CLIENT_TYPE
.set(client_type)
.expect("set_client_name called more than once");
}
pub fn process_user_agent_string() -> String {
let agent_version = agent_version();
let origin = origin_client_info_from_env().unwrap_or_else(|| {
origin_client_info_from_client_type(
CLIENT_TYPE.get().copied().unwrap_or(ClientType::Generic),
Some(agent_version.clone()),
)
});
UserAgent {
origin,
agent_product: "grok-shell",
agent_version,
platform: PlatformInfo::current(),
}
.render()View on GitHub (pinned to bc7f02eddd)
Solutions
- Call set_client_name exactly once, as early as possible in main()
- Guard the call with std::sync::Once so repeats are no-ops
- In tests, run each set_client_name caller in its own test process or avoid calling it in unit tests
- If the value must change, use a library-level API that supports replacement instead of the process-global setter
Example fix
// before set_client_name(ClientType::Cli); // later, possibly again set_client_name(ClientType::Cli); // panics // after static INIT: std::sync::Once = std::sync::Once::new(); INIT.call_once(|| set_client_name(ClientType::Cli));
Defensive patterns
Strategy: validation
Validate before calling
use std::sync::Once; static CLIENT_NAME_INIT: Once = Once::new(); CLIENT_NAME_INIT.call_once(|| xai_grok_http::set_client_name(client_type));
Type guard
null
Try / catch
null // the panic fires on a programming error; guard the call instead of catching it
Prevention
- Call set_client_name exactly once, early in main()
- Wrap in std::sync::Once for idempotency
- In tests, isolate callers into separate processes or skip the global setter
- Search the codebase for all set_client_name call sites before adding a new one
When it happens
Trigger: Calling xai_grok_http::set_client_name twice - e.g. an init path and a fallback init path both running, tests calling it in each test without process isolation, or two libraries in one binary both initializing the client type.
Common situations: Unit tests in the same test binary (shared process) each calling set_client_name; CLI subcommand dispatch initializing twice; a lib and the embedding app both setting the origin client type.
Related errors
- failed to spawn acp-stdin reader thread
- default reqwest client builds
- aws-lc-rs supports the default protocol versions
- failed to build shared HTTP client
- failed to build shared upload HTTP client
AI-assisted analysis of xai-org/grok-build@bc7f02eddd (2026-08-31).
Data as JSON: /api/errors/7f9bfa1fc47da6ef.
Report an issue: GitHub.