moeru-ai/airi · error · Error

Nano Banana API Key not configured

Error message

Nano Banana API Key not configured

What it means

Thrown by the Nano Banana provider's generate() when this.apiKey is empty. The key is set during initialize() from config.nanobananaApiKey (or config.apiKey); if neither is configured, apiKey stays '' and generation is refused before any network call.

Source

Thrown at apps/stage-tamagotchi/src/main/services/airi/widgets/providers/nanobanana.ts:42

  private updateStatus(jobId: string, status: ArtistryJobStatus) {
    this.jobResults.set(jobId, status)
    const callback = this.callbacks.get(jobId)
    if (callback)
      callback(status)
  }

  async initialize(config: any) {
    this.apiKey = config.nanobananaApiKey || config.apiKey || ''
    if (config.nanobananaModel)
      this.defaultModel = config.nanobananaModel
    if (config.nanobananaResolution)
      this.defaultResolution = config.nanobananaResolution
    log.log(`[Nano Banana] Initialized. API Key present: ${!!this.apiKey}`)
  }

  async generate(request: ArtistryRequest): Promise<ArtistryJob> {
    if (!this.apiKey) {
      throw new Error('Nano Banana API Key not configured')
    }

    const jobId = request.extra?.internalJobId || `nanobanana-${Date.now()}`
    const model = request.model || this.defaultModel
    const resolution = request.extra?.resolution || this.defaultResolution

    // Robust image extraction & cleansing
    let base64Image = request.extra?.image || request.extra?.providerOptions?.image || ''
    if (base64Image.includes('base64,'))
      base64Image = base64Image.split('base64,')[1]

    this.runGeneration(jobId, model, resolution, request.prompt, base64Image)

    return {
      jobId,
      providerJobId: jobId,
    }
  }

View on GitHub (pinned to 27111382b4)

Solutions

  1. Set nanobananaApiKey (or apiKey) in the artistry config / globals passed to provider.initialize.
  2. Confirm the config object passed to initialize actually contains the key (log !!this.apiKey after initialize).
  3. Switch to a different provider until the key is configured, or disable generation (provider 'none').
  4. Ensure initialize() runs before generate() — the artistry bridge calls initialize when provider.initialize and activeGlobals exist.

Example fix

// before
await provider.initialize({ model: 'x' }) // no key

// after
await provider.initialize({ nanobananaApiKey: process.env.NANOBANANA_API_KEY, model: 'x' })
Defensive patterns

Strategy: validation

Validate before calling

// Ensure a key is present before selecting this provider
const key = config.nanobananaApiKey || config.apiKey
if (!key) {
  throw new Error('Nano Banana selected but no API key is configured')
}
await provider.initialize({ nanobananaApiKey: key, ...config })

Type guard

function hasNanoBananaKey(config: any): config is { nanobananaApiKey: string } | { apiKey: string } {
  return Boolean((config?.nanobananaApiKey ?? config?.apiKey))
}

Try / catch

try {
  return await provider.generate(request)
} catch (e) {
  if (/API Key not configured/.test(errorMessageFrom(e) ?? '')) {
    return { error: 'Nano Banana API key is missing — configure it in artistry settings' }
  }
  throw e
}

Prevention

When it happens

Trigger: generate() is called before initialize() was called with a config containing a key, or initialize received a config where both nanobananaApiKey and apiKey are empty/undefined. The provider is selected (default or explicit) but its credentials were never supplied.

Common situations: User selected the Nano Banana provider in settings but didn't enter an API key; the config field name changed and initialize no longer reads the stored key; the key env var isn't set in the deployment; initialize was skipped due to missing globals.

Related errors


AI-assisted analysis of moeru-ai/airi@27111382b4 (2026-08-12). Data as JSON: /api/errors/83c5f09bc6603416. Report an issue: GitHub.