nexu-io/open-design · error · Error
no ImageRouter API key — configure it in Settings or set OD_
Error message
no ImageRouter API key — configure it in Settings or set OD_IMAGEROUTER_API_KEY
What it means
Thrown at the top of renderImageRouterImage when credentials.apiKey is falsy. ImageRouter is an OpenAI-compatible gateway reached at IMAGEROUTER_DEFAULT_BASE_URL (https://api.imagerouter.io/v1/openai); the renderer refuses to call /images/generations without a Bearer key. The env var OD_IMAGEROUTER_API_KEY is the documented override.
Source
Thrown at apps/daemon/src/media/index.ts:985
const imgResp = await fetch(entry.url, withMediaRequestInit(ctx));
if (!imgResp.ok) throw new Error(`openai image fetch ${imgResp.status}`);
const arr = await imgResp.arrayBuffer();
bytes = Buffer.from(arr);
} else {
throw new Error('openai response had neither b64_json nor url');
}
const tag = azure ? 'azure-openai' : 'openai';
return {
bytes,
providerNote: `${tag}/${ctx.wireModel} · ${ctx.aspect} · ${bytes.length} bytes`,
suggestedExt: '.png',
};
}
async function renderImageRouterImage(ctx: MediaContext, credentials: ProviderConfig): Promise<RenderResult> {
if (!credentials.apiKey) {
throw new Error(
'no ImageRouter API key — configure it in Settings or set OD_IMAGEROUTER_API_KEY',
);
}
const baseUrl = (credentials.baseUrl || IMAGEROUTER_DEFAULT_BASE_URL).trim();
const wireModel = (credentials.model || ctx.wireModel).trim();
const url = buildOpenAIImageUrl(baseUrl, false);
const body: Record<string, unknown> = {
prompt: ctx.prompt || 'A high-quality reference image.',
model: wireModel,
quality: 'auto',
size: imageRouterSizeFor(ctx.aspect, 'image'),
response_format: 'b64_json',
output_format: 'png',
};
const resp = await fetch(url, withMediaRequestInit(ctx, {
method: 'POST',
headers: {View on GitHub (pinned to 5be4028344)
Solutions
- Set OD_IMAGEROUTER_API_KEY in the daemon environment or add the key under Settings -> Media Providers -> ImageRouter.
- Restart the daemon so the new env value is read.
- Confirm with od media providers that ImageRouter shows a configured key.
- Switch to the direct OpenAI provider if you have an OpenAI key instead.
Example fix
// before od media generate --surface image --model <imagerouter-model> --prompt "..." // after export OD_IMAGEROUTER_API_KEY=sk-ir-... od media generate --surface image --model <imagerouter-model> --prompt "..."
Defensive patterns
Strategy: validation
Validate before calling
function ensureImageRouterCredential(creds: {apiKey?: string} | null): asserts creds is { apiKey: string } {
if (!creds?.apiKey) {
throw new Error('no ImageRouter API key — configure it in Settings or set OD_IMAGEROUTER_API_KEY');
}
}
ensureImageRouterCredential(credentials); Type guard
function hasImageRouterKey(c: {apiKey?:string} | null): c is { apiKey: string } {
return Boolean(c && typeof c.apiKey === 'string' && c.apiKey.length > 0);
} Prevention
- Set OD_IMAGEROUTER_API_KEY in the daemon env, distinct from OPENAI_API_KEY.
- Surface a missing-key badge next to ImageRouter-routed models in the picker.
- Restart the daemon after setting env vars so the new value is read.
When it happens
Trigger: Selecting an ImageRouter-routed image model with no ImageRouter credential stored and no OD_IMAGEROUTER_API_KEY env var; key cleared from Settings but model still selected.
Common situations: User added an OpenAI key but ImageRouter needs its own; env var not exported in the daemon's process; trial key expired.
Related errors
- no OpenAI credential - configure an API key in Settings or s
- no OpenAI credential — configure an API key in Settings or s
- Custom Image API base URL required — configure an OpenAI-com
- Custom Image API model required — configure the provider mod
- ${providerTag} ${resp.status}: ${truncate(text, 240)}
AI-assisted analysis of nexu-io/open-design@5be4028344 (2026-08-12).
Data as JSON: /api/errors/f85b4b7e0cee76e1.
Report an issue: GitHub.