linshenkx/prompt-optimizer · error · CompareCalculationError
Text comparison calculation failed: ${errorMessage}
Error message
Text comparison calculation failed: ${errorMessage} What it means
Thrown when the AI model's response to a reference-image style extraction call comes back empty (blank or non-string content). The library calls a multimodal model with responseMimeType 'application/json' and requires a non-empty text body before it can normalize the result into a prompt preview. An empty body means the model refused, returned only non-text parts, or the backend stripped the content.
Source
Thrown at packages/core/src/services/compare/service.ts:55
const finalOptions = { ...DEFAULT_OPTIONS, ...options };
// 执行对比
const fragments = this.performTextComparison(original, optimized, finalOptions);
// 生成统计信息
const summary = this.generateSummary(fragments);
return {
fragments,
summary
};
} catch (error) {
if (error instanceof CompareValidationError) {
throw error;
}
const errorMessage = error instanceof Error ? error.message : String(error);
throw new CompareCalculationError(
`Text comparison calculation failed: ${errorMessage}`
);
}
}
/**
* 验证输入参数
*/
private validateInput(original: string, optimized: string): void {
if (typeof original !== 'string') {
throw new CompareValidationError('Original text must be a string');
}
if (typeof optimized !== 'string') {
throw new CompareValidationError('Optimized text must be a string');
}
}
/**View on GitHub (pinned to 3e677b1d9f)
Solutions
- Check response.content shape — if it's an array of parts, extract text parts before trimming
- Retry the call; transient empty responses from safety filters or rate limits often succeed on retry
- Verify the model actually supports image (multimodal) input and the image was attached correctly
- Inspect the raw model response (log it) to see whether the refusal/safety block reason is present
- Fall back to a default reference prompt preview instead of failing the whole flow
Example fix
// before
const rawText = typeof response.content === 'string' ? response.content.trim() : ''
if (!rawText) {
throw new Error('Model did not return a valid structured prompt')
}
// after (tolerate array-of-parts responses)
const content = response.content
const rawText = (typeof content === 'string'
? content
: Array.isArray(content)
? content.filter((p): p is { text: string } => typeof p?.text === 'string').map(p => p.text).join('')
: '').trim()
if (!rawText) {
throw new Error('Model did not return a valid structured prompt')
} Defensive patterns
Strategy: retry
Validate before calling
const content = response?.content
const isEmpty =
typeof content !== 'string' || content.trim().length === 0
if (isEmpty) {
// don't call resolveReferencePromptPreview-dependent flow; retry or fallback
await retryWithBackoff(callModel)
} Type guard
function hasNonEmptyContent(response: unknown): response is { content: string } {
return (
typeof response === 'object' &&
response !== null &&
typeof (response as { content?: unknown }).content === 'string' &&
((response as { content: string }).content.trim().length > 0)
)
} Try / catch
try {
const preview = await extractor.resolveReferencePromptPreview(/* ... */)
} catch (error) {
if (error instanceof Error && error.message === 'Model did not return a valid structured prompt') {
return DEFAULT_REFERENCE_PROMPT_PREVIEW // graceful fallback
}
throw error
} Prevention
- Log raw model responses in dev to spot empty/safety-blocked replies
- Verify the model supports image input before enabling reference-image features
- Implement one retry with backoff for transient empty responses
When it happens
Trigger: Calling resolveReferencePromptPreview / the preview flow on ImageStyleExtractor with a reference image, where the model response's content is not a string or trims to empty (e.g. safety refusal, empty candidates, unsupported image input).
Common situations: Using a model that doesn't support image input; safety filter blocking the image; API key/quota issues returning an empty body; model returning content as an array of parts instead of a plain string; rate limiting that silently degrades responses.
Related errors
- Optimized text must be a string
- CONTEXT_ERROR_CODES.IMPORT_FORMAT_ERROR
- CONTEXT_ERROR_CODES.INVALID_STORE
- API returned empty model list
AI-assisted analysis of linshenkx/prompt-optimizer@3e677b1d9f (2026-08-27).
Data as JSON: /api/errors/96341723d0dafb09.
Report an issue: GitHub.