{"record":{"id":"3bdc13c2e395e961","repo":"nexu-io/open-design","slug":"no-xai-credentials-sign-in-with-your-supergrok-s","errorCode":null,"errorMessage":"no xAI credentials — sign in with your SuperGrok subscription (in OD or via `hermes auth add xai-oauth`), set XAI_API_KEY, or configure a key in Settings","messagePattern":"no xAI credentials — sign in with your SuperGrok subscription \\(in OD or via `hermes auth add xai-oauth`\\), set XAI_API_KEY, or configure a key in Settings","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"apps/daemon/src/media/index.ts","lineNumber":1614,"sourceCode":"//\n// Docs: https://docs.x.ai/developers/model-capabilities/{images,video}/generation\n//   * Image: POST /v1/images/generations — synchronous, returns\n//            {data:[{b64_json|url}]}; we ask for b64_json so the bytes\n//            arrive in one round-trip.\n//   * Video: POST /v1/videos/generations — may return the finished video\n//            inline ({status:'done', video:{url}}) or an async stub\n//            ({id, status:'pending'}); in the async case we poll\n//            GET /v1/videos/{id} until status flips to done/failed.\n//\n// xAI's video model produces native audio (background music + SFX +\n// ambient) synchronised with the visual; that's the headline\n// differentiator vs Seedance and Sora and is why grok-imagine-video\n// declares the `audio` capability.\n// ---------------------------------------------------------------------------\n\nasync function renderGrokImage(ctx: MediaContext, credentials: ProviderConfig): Promise<RenderResult> {\n  if (!credentials.apiKey) {\n    throw new Error(\n      'no xAI credentials — sign in with your SuperGrok subscription (in OD or via `hermes auth add xai-oauth`), set XAI_API_KEY, or configure a key in Settings',\n    );\n  }\n  const baseUrl = (credentials.baseUrl || 'https://api.x.ai/v1').replace(/\\/$/, '');\n\n  const aspectRatio = grokAspectFor(ctx.aspect);\n  const body = {\n    model: ctx.wireModel,\n    prompt: ctx.prompt || 'A high-quality reference image.',\n    n: 1,\n    aspect_ratio: aspectRatio,\n    response_format: 'b64_json',\n  };\n  const resp = await fetch(`${baseUrl}/images/generations`, withMediaRequestInit(ctx, {\n    method: 'POST',\n    headers: {\n      'authorization': `Bearer ${credentials.apiKey}`,\n      'content-type': 'application/json',","sourceCodeStart":1596,"sourceCodeEnd":1632,"githubUrl":"https://github.com/nexu-io/open-design/blob/5be4028344c2eb4c667c5a97bda8f750c5597ef7/apps/daemon/src/media/index.ts#L1596-L1632","documentation":"Thrown at the top of `renderGrokImage` when no xAI credential is available. xAI auth has three sources — SuperGrok OAuth (via OD sign-in or `hermes auth add xai-oauth`), the `XAI_API_KEY` env var, or a key in Settings — and the message lists all three so the user can pick whichever they have.","triggerScenarios":"`credentials.apiKey` is falsy after `resolveProviderConfig('grok')` resolves the key from OAuth, `XAI_API_KEY`, or Settings, while the selected model is a `provider: 'grok'` image model (e.g. `grok-imagine-image`).","commonSituations":"(1) User picked a Grok Imagine model before signing in; (2) SuperGrok OAuth token expired and wasn't refreshed; (3) `XAI_API_KEY` set in a different shell than the daemon; (4) key cleared from Settings but model selection persisted.","solutions":["Sign in with SuperGrok via OD Settings, or run `hermes auth add xai-oauth`, or set `XAI_API_KEY`, or enter a key in Settings → Providers → xAI.","Restart the daemon after adding/refreshing the credential so `resolveProviderConfig` re-reads it.","If using OAuth and it expired, re-run the OAuth flow."],"exampleFix":"// before\nod media generate --surface image --model grok-imagine-image --prompt '...'\n\n// after (option A: env)\nexport XAI_API_KEY=xai-xxxx\nod media generate --surface image --model grok-imagine-image --prompt '...'\n\n// after (option B: OAuth)\nhermes auth add xai-oauth","handlingStrategy":"validation","validationCode":"function ensureGrokCreds(credentials: ProviderConfig): void {\n  if (!credentials.apiKey) {\n    throw new Error('no xAI credentials — sign in with SuperGrok, set XAI_API_KEY, or configure a key in Settings');\n  }\n}\n// call before renderGrokImage(ctx, credentials)\nensureGrokCreds(credentials);","typeGuard":"function hasGrokCreds(c: ProviderConfig): c is ProviderConfig & { apiKey: string } {\n  return typeof c.apiKey === 'string' && c.apiKey.length > 0;\n}","tryCatchPattern":null,"preventionTips":["Provide one of: SuperGrok OAuth (OD sign-in or `hermes auth add xai-oauth`), `XAI_API_KEY`, or a Settings key.","Re-run the OAuth flow if the SuperGrok token expires.","Restart the daemon after adding/refreshing a credential."],"tags":["xai","grok","api-key","oauth","config"],"backgroundTag":null,"analyzedSha":"5be4028344c2eb4c667c5a97bda8f750c5597ef7","analyzedAt":"2026-08-12T12:03:58.812Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}