nexu-io/open-design · error · Error

no Nano Banana API key — configure it in Settings or set OD_

Error message

no Nano Banana API key — configure it in Settings or set OD_NANOBANANA_API_KEY

What it means

Thrown by renderNanoBananaImage (Google Gemini 'Nano Banana' / gemini-2.5-flash-image provider) before any network call when credentials.apiKey is empty. It is the contract guard ensuring a key is present so the request can be authorized against the v1beta generateContent endpoint.

Source

Thrown at apps/daemon/src/media/index.ts:1673

  } else {
    throw new Error('grok image response missing b64_json/url');
  }
  // xAI's Imagine returns JPEG by default (no format option in the API
  // surface), but PNG/WebP are technically possible. Sniff the magic
  // bytes so the on-disk extension matches reality — saving JPEG bytes
  // as `.png` confuses Finder previews and any downstream consumer that
  // trusts the extension.
  return {
    bytes,
    providerNote: `grok/${ctx.wireModel} · ${aspectRatio} · ${bytes.length} bytes`,
    suggestedExt: sniffImageExt(bytes),
  };
}

async function renderNanoBananaImage(ctx: MediaContext, credentials: ProviderConfig): Promise<RenderResult> {
  const apiKey = credentials.apiKey;
  if (!apiKey) {
    throw new Error(
      'no Nano Banana API key — configure it in Settings or set OD_NANOBANANA_API_KEY',
    );
  }

  const baseUrl = (credentials.baseUrl || NANOBANANA_DEFAULT_BASE_URL).replace(/\/$/, '');
  const wireModel = (credentials.model || ctx.wireModel || NANOBANANA_DEFAULT_MODEL).trim();
  const body = {
    contents: [{
      parts: [{
        text: ctx.prompt || 'A high-quality reference image.',
      }],
    }],
    generationConfig: {
      responseModalities: ['IMAGE'],
      imageConfig: {
        aspectRatio: nanoBananaAspectFor(ctx.aspect),
        imageSize: NANOBANANA_DEFAULT_IMAGE_SIZE,
      },

View on GitHub (pinned to 5be4028344)

Solutions

  1. Open Settings in the web UI and paste the Nano Banana / Google AI Studio API key into the provider config.
  2. Or export OD_NANOBANANA_API_KEY in the daemon process environment and restart.
  3. If the key was set but the error persists, verify credentials.apiKey is actually loaded by the provider credentials loader (check the media provider registry).

Example fix

// before
const apiKey = credentials.apiKey;
if (!apiKey) {
  throw new Error('no Nano Banana API key — configure it in Settings or set OD_NANOBANANA_API_KEY');
}

// after — fall back to env at the call site so headless setups work without UI
const apiKey = credentials.apiKey || process.env.OD_NANOBANANA_API_KEY;
if (!apiKey) {
  throw new Error('no Nano Banana API key — configure it in Settings or set OD_NANOBANANA_API_KEY');
}
Defensive patterns

Strategy: validation

Validate before calling

// Pre-flight check before invoking renderNanoBananaImage
function hasNanoBananaCredentials(creds: ProviderConfig): boolean {
  return Boolean(creds.apiKey && creds.apiKey.trim());
}

// at the call site, before dispatching:
if (ctx.providerId === 'nanobanana' && !hasNanoBananaCredentials(credentials)) {
  return { kind: 'config-error', message: 'Add your Nano Banana API key in Settings or set OD_NANOBANANA_API_KEY.' };
}

Type guard

function nanoBananaConfigured(creds: ProviderConfig, env = process.env): boolean {
  return Boolean((creds.apiKey && creds.apiKey.trim()) || env.OD_NANOBANANA_API_KEY);
}

Try / catch

// caller wraps the dispatch
try {
  await renderNanoBananaImage(ctx, credentials);
} catch (e) {
  if (/no Nano Banana API key/.test(String(e))) {
    return presentConfigPrompt('nanobanana');
  }
  throw e;
}

Prevention

When it happens

Trigger: User selects the Nano Banana provider in Settings without entering an API key, OD_NANOBANANA_API_KEY env var is unset, or the credentials store failed to persist the key. The error message names both remediation paths explicitly.

Common situations: First-time provider setup where the user picked the model but skipped the key field; deploying the daemon in a fresh environment without exporting OD_NANOBANANA_API_KEY; key cleared by a settings reset.

Related errors


AI-assisted analysis of nexu-io/open-design@5be4028344 (2026-08-12). Data as JSON: /api/errors/d654bf235215d748. Report an issue: GitHub.