nexu-io/open-design · error · Error
no xAI credentials — sign in with your SuperGrok subscriptio
Error message
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
What it means
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.
Source
Thrown at apps/daemon/src/media/index.ts:1614
//
// Docs: https://docs.x.ai/developers/model-capabilities/{images,video}/generation
// * Image: POST /v1/images/generations — synchronous, returns
// {data:[{b64_json|url}]}; we ask for b64_json so the bytes
// arrive in one round-trip.
// * Video: POST /v1/videos/generations — may return the finished video
// inline ({status:'done', video:{url}}) or an async stub
// ({id, status:'pending'}); in the async case we poll
// GET /v1/videos/{id} until status flips to done/failed.
//
// xAI's video model produces native audio (background music + SFX +
// ambient) synchronised with the visual; that's the headline
// differentiator vs Seedance and Sora and is why grok-imagine-video
// declares the `audio` capability.
// ---------------------------------------------------------------------------
async function renderGrokImage(ctx: MediaContext, credentials: ProviderConfig): Promise<RenderResult> {
if (!credentials.apiKey) {
throw new Error(
'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',
);
}
const baseUrl = (credentials.baseUrl || 'https://api.x.ai/v1').replace(/\/$/, '');
const aspectRatio = grokAspectFor(ctx.aspect);
const body = {
model: ctx.wireModel,
prompt: ctx.prompt || 'A high-quality reference image.',
n: 1,
aspect_ratio: aspectRatio,
response_format: 'b64_json',
};
const resp = await fetch(`${baseUrl}/images/generations`, withMediaRequestInit(ctx, {
method: 'POST',
headers: {
'authorization': `Bearer ${credentials.apiKey}`,
'content-type': 'application/json',View on GitHub (pinned to 5be4028344)
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.
Example fix
// before od media generate --surface image --model grok-imagine-image --prompt '...' // after (option A: env) export XAI_API_KEY=xai-xxxx od media generate --surface image --model grok-imagine-image --prompt '...' // after (option B: OAuth) hermes auth add xai-oauth
Defensive patterns
Strategy: validation
Validate before calling
function ensureGrokCreds(credentials: ProviderConfig): void {
if (!credentials.apiKey) {
throw new Error('no xAI credentials — sign in with SuperGrok, set XAI_API_KEY, or configure a key in Settings');
}
}
// call before renderGrokImage(ctx, credentials)
ensureGrokCreds(credentials); Type guard
function hasGrokCreds(c: ProviderConfig): c is ProviderConfig & { apiKey: string } {
return typeof c.apiKey === 'string' && c.apiKey.length > 0;
} Prevention
- 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.
When it happens
Trigger: `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`).
Common situations: (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.
Related errors
- xAI OAuth state not found or expired
- xAI OAuth state mismatch: expected serverId=${XAI_PROVIDER_I
- auth server ${authServer.issuer} does not advertise a regist
- no Volcengine Ark API key — configure it in Settings or set
- grok image ${resp.status}: ${truncate(text, 240)}
AI-assisted analysis of nexu-io/open-design@5be4028344 (2026-08-12).
Data as JSON: /api/errors/3bdc13c2e395e961.
Report an issue: GitHub.