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 errorView on GitHub (pinned to 81571269ad)
Solutions
- Disable the generate button while currentGeneratingId is non-null (subscribe to the store in the UI).
- Ensure every start path reaches its finally that calls setCurrentGeneratingId(null).
- Return a typed 'busy' result instead of throwing so the UI can ignore it without error UX.
- 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
- Disable the generate button while currentGeneratingId is non-null.
- Ensure every start path reaches the finally that clears currentGeneratingId.
- Return a non-throwing 'busy' result for an expected precondition.
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
- No readable text content found in EPUB file
- Embedding batch failed: expected ${batchTexts.length}, got $
- MiniMax OAuth state mismatch
- OAuth state mismatch
- Failed to mark attachment ${attachment.id} ready
AI-assisted analysis of chatboxai/chatbox@81571269ad (2026-08-12).
Data as JSON: /api/errors/9b1916a829603dbc.
Report an issue: GitHub.