chatboxai/chatbox · warning · Error
No readable text content found in EPUB file
Error message
No readable text content found in EPUB file
What it means
Thrown at the top of CustomGemini.paint() when `isGeminiImageModel(this.options.model.modelId)` is false. isGeminiImageModel (in definitions/image-models.ts) returns true only when the model id contains both 'gemini' and 'image'. paint() is the image-generation entry point, so calling it on a text-only Gemini model is a programmer/UX error, not a network condition — the guard fires before any API call.
Source
Thrown at src/main/file-parser.ts:309
return plainText || null
} catch (chapterError) {
log.warn(`Failed to read chapter ${chapter.id}, skipping:`, chapterError)
return null // Return null for failed chapters to continue processing
}
}
// Extract text from all chapters using concurrent processing
log.info(`Starting concurrent processing of ${epub.flow.length} chapters with concurrency: 8`)
const chapterResults = await concurrentMap(epub.flow as { id: string }[], processChapter, 8)
const chapterTexts = chapterResults.filter((text: string | null) => text !== null) as string[]
log.info(`Successfully processed ${chapterTexts.length}/${epub.flow.length} chapters`)
const fullText = chapterTexts.join('\n\n')
if (!fullText) {
throw new Error('No readable text content found in EPUB file')
}
log.info(`Successfully extracted ${fullText.length} characters from ${chapterTexts.length} chapters`)
resolve(fullText)
} catch (error) {
log.error('Error extracting EPUB content:', error)
reject(error)
}
})
epub.parse()
})
}
View on GitHub (pinned to 81571269ad)
Solutions
- Before calling paint(), gate the UI on `isGeminiImageModel(modelId)` (model id must include both 'gemini' and 'image') and only enable the paint action for matching models.
- Switch the selected model to a known Gemini image model such as `gemini-2.0-flash-exp-image-generation` or `gemini-2.5-flash-image-preview`.
- If you maintain a custom provider, ensure the model id for image-capable models contains the substring 'image' so the heuristic matches.
- Update image-models.ts if Google ships a new image model whose id does not match the `gemini`+`image` rule.
Example fix
// before
await model.paint({ prompt, num: 1 }) // throws on text models
// after
guard before calling:
if (!isGeminiImageModel(session.modelId)) {
showWarning('Select a Gemini image model to generate images')
} else {
await model.paint({ prompt, num: 1 })
} Defensive patterns
Strategy: validation
Validate before calling
function canPaint(modelId: string): boolean {
return modelId.includes('gemini') && modelId.includes('image')
}
// before invoking paint:
if (!canPaint(session.modelId)) disablePaintUI() Type guard
import { isGeminiImageModel } from '../image-models'
function assertImageCapable(modelId: string): void {
if (!isGeminiImageModel(modelId)) throw new Error(`Model ${modelId} cannot generate images`)
} Try / catch
try { await gemini.paint({ prompt, num: 1 }) }
catch (e) {
if (e instanceof ApiError && e.message.includes('does not support image generation')) {
showWarning('Switch to a Gemini image model to paint')
return []
}
throw e
} Prevention
- Bind the paint button's `disabled` state to isGeminiImageModel(selectedModelId).
- Update image-models.ts when Google ships image models whose id breaks the gemini+image rule.
- Never invoke paint() on a model chosen by display name — always check the underlying id.
When it happens
Trigger: UI invokes paint() with the currently selected model id even though it is a text model (e.g. `gemini-2.0-flash`, `gemini-1.5-pro`); a saved session has a non-image Gemini model selected when the user clicks the paint button; model list refresh replaced an image model id with its text counterpart; the model id does not contain the literal substring 'image' (e.g. a renamed alias).
Common situations: User selects 'gemini-2.5-flash' (text) and opens the image-generation panel expecting it to work; a custom Gemini provider exposes a model under a nickname whose underlying id lacks 'image'; version upgrade renamed the image model (e.g. from `gemini-2.0-flash-exp-image-generation` to something without 'image' in the id) so isGeminiImageModel no longer recognises it.
Related errors
- Embedding batch failed: expected ${batchTexts.length}, got $
- Image generation requires an active chat session.
- Missing --prompt.
- --style must be vivid or natural.
- Image model is not available: ${provider}/${modelId}. Use "c
AI-assisted analysis of chatboxai/chatbox@81571269ad (2026-08-12).
Data as JSON: /api/errors/bf3189fec35fdbbc.
Report an issue: GitHub.