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

  1. Check response.content shape — if it's an array of parts, extract text parts before trimming
  2. Retry the call; transient empty responses from safety filters or rate limits often succeed on retry
  3. Verify the model actually supports image (multimodal) input and the image was attached correctly
  4. Inspect the raw model response (log it) to see whether the refusal/safety block reason is present
  5. 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

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


AI-assisted analysis of linshenkx/prompt-optimizer@3e677b1d9f (2026-08-27). Data as JSON: /api/errors/96341723d0dafb09. Report an issue: GitHub.