chatboxai/chatbox · warning · Error

Another image is being generated. Please wait.

Error message

Another image is being generated. Please wait.

What it means

Single-flight guard at the top of startImageGeneration. The store tracks currentGeneratingId; if it is non-null another generation owns the slot and the call is rejected before creating a record. This prevents two concurrent generations from racing on the shared currentAbortController and store state.

Source

Thrown at src/renderer/stores/imageGenerationActions.ts:131

/**
 * Starts image generation without waiting for the provider task to finish.
 * Callers that need background-task notifications can observe `completion`;
 * existing UI callers can keep using `createAndGenerate` and only consume the id.
 */
export async function startImageGeneration(
  params: GenerateImageParams,
  options: StartImageGenerationOptions = {}
): Promise<ImageGenerationHandle> {
  const store = imageGenerationStore.getState()

  // Normalize: 'auto' means no aspect ratio constraint
  if (params.aspectRatio === 'auto') {
    params = { ...params, aspectRatio: undefined }
  }

  if (store.currentGeneratingId !== null) {
    throw new Error('Another image is being generated. Please wait.')
  }

  const record = await createRecord({
    prompt: params.prompt,
    referenceImages: params.referenceImages,
    model: params.model,
    dalleStyle: params.dalleStyle,
    imageGenerateNum: params.imageGenerateNum,
    parentIds: params.parentIds,
    aspectRatio: params.aspectRatio,
    source: params.source,
  })

  try {
    await options.onRecordCreated?.(record)
  } catch (error) {
    await updateRecord(record.id, getErrorRecordUpdate(error))
    throw error

View on GitHub (pinned to 81571269ad)

Solutions

  1. Disable the generate button while currentGeneratingId is non-null (subscribe to the store in the UI).
  2. Ensure every start path reaches its finally that calls setCurrentGeneratingId(null).
  3. Return a typed 'busy' result instead of throwing so the UI can ignore it without error UX.
  4. Add a timeout/watchdog that clears a stuck currentGeneratingId if no progress for N seconds.

Example fix

// before
if (store.currentGeneratingId !== null) {
  throw new Error('Another image is being generated. Please wait.')
}
// after
if (store.currentGeneratingId !== null) {
  return { status: 'busy' } as ImageGenerationHandle
}
Defensive patterns

Strategy: validation

Validate before calling

const busy = imageGenerationStore.getState().currentGeneratingId !== null
if (busy) return // ignore secondary trigger

Type guard

function isSlotFree(s: { currentGeneratingId: string | null }): boolean {
  return s.currentGeneratingId === null
}

Prevention

When it happens

Trigger: startImageGeneration invoked while imageGenerationStore.getState().currentGeneratingId !== null. Causes: double-click on the generate button, two UI surfaces triggering at once, or a previous generation that failed to clear currentGeneratingId in its finally block.

Common situations: User double-taps generate, a previous generation crashed before reaching the finally that resets currentGeneratingId (leaked lock), or retry/resume invoked concurrently with an in-flight start.

Related errors


AI-assisted analysis of chatboxai/chatbox@81571269ad (2026-08-12). Data as JSON: /api/errors/9b1916a829603dbc. Report an issue: GitHub.