linshenkx/prompt-optimizer · warning · DataInvalidFormatError

Unrecognized data structure

Error message

Unrecognized data structure

What it means

OptimizationError thrown by validateMessageOptimizationRequest when the located selected message has empty/whitespace content (or content undefined). The service refuses to optimize a message with nothing to rewrite — the final fail-fast check before template resolution.

Source

Thrown at packages/core/src/services/data/manager.ts:124

      throw new DataInvalidFormatError('Data must be an object')
    }

    // Support both old and new format for backward compatibility
    let dataToImport: Record<string, any>;

    // New format: { version: 1, data: { ... } }
    if (exportData.version) {
      if (!exportData.data || typeof exportData.data !== 'object' || Array.isArray(exportData.data)) {
        throw new DataInvalidFormatError('"data" property is missing or not an object')
      }
      dataToImport = exportData.data;
    }
    // Old format: direct data object { history: [...], models: [...], ... }
    else if (exportData.history || exportData.models || exportData.imageModels || exportData.userTemplates || exportData.userSettings || exportData.contexts) {
      dataToImport = exportData;
    }
    else {
      throw new DataInvalidFormatError('Unrecognized data structure')
    }

    const errors: string[] = [];

    // 使用各服务的importData接口
    const serviceMap = [
      { service: this.historyManager, dataKey: 'history' },
      { service: this.modelManager, dataKey: 'models' },
      ...(this.imageModelManager ? [{ service: this.imageModelManager, dataKey: 'imageModels' }] : []),
      { service: this.templateManager, dataKey: 'userTemplates' },
      { service: this.preferenceService, dataKey: 'userSettings' },
      { service: this.contextRepo, dataKey: 'contexts' }
    ];

    for (const { service, dataKey } of serviceMap) {
      if (dataToImport[dataKey] !== undefined) {
        try {
          await service.importData(dataToImport[dataKey]);

View on GitHub (pinned to 3e677b1d9f)

Solutions

  1. Filter selectable messages to those with non-empty trimmed content in the UI.
  2. If optimizing image-only messages is required, populate content with a caption or placeholder text first.
  3. Audit any serialization layer that could drop the content field.
  4. Catch and show 'this message has no text to optimize'.

Example fix

// before
const target = messages.find(m => m.id === selectedId)!; // may be empty
await promptService.optimizeMessage({ selectedMessageId: selectedId, messages, modelKey });

// after
const target = messages.find(m => m.id === selectedId);
if (!target?.content?.trim()) return; // not optimizable
await promptService.optimizeMessage({ selectedMessageId: selectedId, messages, modelKey });
Defensive patterns

Strategy: validation

Validate before calling

const target = messages.find(m => m.id === selectedId);
if (!target?.content?.trim()) throw new Error('Message has no text');

Type guard

function hasTextContent(m: unknown): boolean {
  return typeof (m as any)?.content === 'string' && (m as any).content.trim() !== '';
}

Try / catch

try { await svc.optimizeMessage(req); } catch (e) { if (e instanceof OptimizationError && /content cannot be empty/.test(e.message)) showMessage('Nothing to optimize'); }

Prevention

When it happens

Trigger: Optimizing a message whose content is '' or only whitespace — e.g. an image-only message with no text, a placeholder/system marker message, or content stripped during serialization.

Common situations: Multimodal messages where text is optional, messages created as markers/dividers, content field dropped by a DTO mapper, or whitespace-only drafts saved by a buggy editor.

Related errors


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