{"record":{"id":"7f9bfa1fc47da6ef","repo":"xai-org/grok-build","slug":"set-client-name-called-more-than-once","errorCode":null,"errorMessage":"set_client_name called more than once","messagePattern":"set_client_name called more than once","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/codegen/xai-grok-http/src/lib.rs","lineNumber":177,"sourceCode":"                self.origin.product,\n                self.agent_product,\n                self.agent_version,\n                self.platform.os,\n                self.platform.arch,\n            ),\n        }\n    }\n}\n\nfn agent_version() -> String {\n    xai_grok_version::VERSION.to_string()\n}\n\n/// Set the process-level fallback origin client type for `User-Agent`.\npub fn set_client_name(client_type: ClientType) {\n    CLIENT_TYPE\n        .set(client_type)\n        .expect(\"set_client_name called more than once\");\n}\n\npub fn process_user_agent_string() -> String {\n    let agent_version = agent_version();\n    let origin = origin_client_info_from_env().unwrap_or_else(|| {\n        origin_client_info_from_client_type(\n            CLIENT_TYPE.get().copied().unwrap_or(ClientType::Generic),\n            Some(agent_version.clone()),\n        )\n    });\n\n    UserAgent {\n        origin,\n        agent_product: \"grok-shell\",\n        agent_version,\n        platform: PlatformInfo::current(),\n    }\n    .render()","sourceCodeStart":159,"sourceCodeEnd":195,"githubUrl":"https://github.com/xai-org/grok-build/blob/bc7f02eddd3d84085849dc19ed216f11c23b0571/crates/codegen/xai-grok-http/src/lib.rs#L159-L195","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nset_client_name(ClientType::Cli);\n// later, possibly again\nset_client_name(ClientType::Cli); // panics\n// after\nstatic INIT: std::sync::Once = std::sync::Once::new();\nINIT.call_once(|| set_client_name(ClientType::Cli));","handlingStrategy":"validation","validationCode":"use std::sync::Once;\nstatic CLIENT_NAME_INIT: Once = Once::new();\nCLIENT_NAME_INIT.call_once(|| xai_grok_http::set_client_name(client_type));","typeGuard":"null","tryCatchPattern":"null // the panic fires on a programming error; guard the call instead of catching it","preventionTips":["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"],"tags":["global-state","panics","initialization","rust"],"backgroundTag":"global-state-double-init","analyzedSha":"bc7f02eddd3d84085849dc19ed216f11c23b0571","analyzedAt":"2026-08-31T04:59:42.031Z","schemaVersion":2},"datasetVersion":"2026-08-31T09:17:48.483Z"}