{"record":{"id":"05f7d5e2323bdfbc","repo":"tonhowtf/omniget","slug":"grok-no-key","errorCode":"GROK_NO_KEY","errorMessage":"GROK_NO_KEY","messagePattern":"GROK_NO_KEY","errorType":"error_code","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"src-tauri/omniget-core/src/core/tools/x/grok.rs","lineNumber":141,"sourceCode":"        \"x\" => \"x\",\n        _ => {\n            if !cfg.xai_key.is_empty() {\n                \"xai\"\n            } else {\n                \"x\"\n            }\n        }\n    };\n    if backend == \"xai\" {\n        ask_xai(&cfg, req).await\n    } else {\n        ask_x(&cfg, req).await\n    }\n}\n\nasync fn ask_xai(cfg: &GrokConfig, req: GrokRequest) -> anyhow::Result<GrokAnswer> {\n    if cfg.xai_key.is_empty() {\n        anyhow::bail!(\"GROK_NO_KEY\");\n    }\n    let model = if req.model.trim().is_empty() {\n        cfg.xai_model.clone()\n    } else {\n        req.model.trim().to_string()\n    };\n    let mut tools = Vec::new();\n    if req.x_search {\n        let mut t = json!({ \"type\": \"x_search\" });\n        let handles: Vec<String> = req\n            .handles\n            .iter()\n            .map(|h| h.trim().trim_start_matches('@').to_string())\n            .filter(|h| !h.is_empty())\n            .take(20)\n            .collect();\n        if !handles.is_empty() {\n            t[\"allowed_x_handles\"] = json!(handles);","sourceCodeStart":123,"sourceCodeEnd":159,"githubUrl":"https://github.com/tonhowtf/omniget/blob/8600b91f4246848bac346874daa9e61c1fc5677a/src-tauri/omniget-core/src/core/tools/x/grok.rs#L123-L159","documentation":"ask_xai in the X/Grok tool bails with GROK_NO_KEY when GrokConfig.xai_key is an empty string. The library refuses to call the xAI API without credentials instead of sending a doomed request. It is a pre-flight configuration guard.","triggerScenarios":"Calling ask() which routes to ask_xai while cfg.xai_key is empty — e.g. the Grok config was loaded from a file/env where XAI_KEY was never set, or was set to \"\".","commonSituations":"Fresh checkout where the .env/config with the xAI key was never created; CI environment lacking the secret; key intentionally blanked after a rotation failure.","solutions":["Set the xAI API key in the config that populates GrokConfig.xai_key (env var or config file) before calling ask().","Verify the key is loaded (non-empty) at startup and fail fast with a clear message if not.","Check that the key is not being trimmed/overwritten to empty by config loading code."],"exampleFix":"// before\nlet cfg = load_grok_config();\nlet ans = ask(&cfg, req).await?;\n// after\nlet cfg = load_grok_config();\nif cfg.xai_key.is_empty() {\n    return Err(anyhow::anyhow!(\"xAI key missing: set XAI_KEY in config before calling ask\"));\n}\nlet ans = ask(&cfg, req).await?;","handlingStrategy":"validation","validationCode":"if cfg.xai_key.trim().is_empty() {\n    return Err(anyhow::anyhow!(\"xAI API key not configured (set XAI_KEY)\"));\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Validate all required API keys at app startup, before any request path runs.","Keep keys in a single config struct with an assert-on-load check.","Document the required env var and fail fast in CI when it is absent."],"tags":["config","api-key","missing-credentials"],"backgroundTag":"missing-api-key","analyzedSha":"8600b91f4246848bac346874daa9e61c1fc5677a","analyzedAt":"2026-09-12T14:29:19.317Z","contentChangedAt":"2026-09-12T14:29:19.317Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}