{"record":{"id":"db98943d8b1c2b64","repo":"linshenkx/prompt-optimizer","slug":"empty-prompt-messages","errorCode":null,"errorMessage":"Empty prompt.messages","messagePattern":"Empty prompt\\.messages","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/ui/src/composables/app/useAppPromptGardenImport.ts","lineNumber":564,"sourceCode":"    const format = prompt && (prompt.format === 'text' || prompt.format === 'messages')\n      ? (prompt.format as 'text' | 'messages')\n      : null\n    if (!format) {\n      throw new Error('Missing prompt.format')\n    }\n\n    let promptText: string | undefined\n    let promptMessages: ConversationMessage[] | undefined\n    if (format === 'text') {\n      const t = prompt && typeof prompt.text === 'string' ? prompt.text : ''\n      if (!t.trim()) {\n        throw new Error('Empty prompt.text')\n      }\n      promptText = t\n    } else {\n      const msgs = normalizeImportedConversationMessages(prompt?.messages)\n      if (!msgs.length) {\n        throw new Error('Empty prompt.messages')\n      }\n      promptMessages = msgs\n    }\n\n    if (!Array.isArray(data.variables)) {\n      throw new Error('Missing variables')\n    }\n    const variablesForImport = data.variables\n      .map((v): { name: string; defaultValue?: string } => {\n        if (!isPlainObject(v)) return { name: '' }\n        const name = typeof v.name === 'string' ? v.name.trim() : ''\n        const defaultValue = typeof v.defaultValue === 'string' ? v.defaultValue : undefined\n        return { name, defaultValue }\n      })\n      .filter((v) => isValidVariableName(v.name))\n\n    const snapshotVariables = data.variables\n      .map((v): GardenSnapshotVariable | null => {","sourceCodeStart":546,"sourceCodeEnd":582,"githubUrl":"https://github.com/linshenkx/prompt-optimizer/blob/3e677b1d9f7e0493c142c175560531e7ae786dce/packages/ui/src/composables/app/useAppPromptGardenImport.ts#L546-L582","documentation":"When format === 'messages', the prompt body's `messages` array is passed through normalizeImportedConversationMessages; if normalization yields zero messages, this error is thrown. Zero results can mean the input was empty or every entry failed normalization (bad role, invalid structure).","triggerScenarios":"prompt.messages is undefined/null/[] or contains only entries that normalizeImportedConversationMessages filters out (missing/invalid role or content).","commonSituations":"Messages exported with roles the importer doesn't recognize (e.g. 'tool', 'system2'); entries whose content is an unsupported shape; empty conversations exported as valid; upstream renamed 'role'/'content' keys.","solutions":["Inspect prompt.messages and confirm each entry has a recognized role and valid content shape","Log which entries normalizeImportedConversationMessages drops to find the invalid message structure","Re-export with a conversation containing at least one valid user/assistant message"],"exampleFix":"// before\n{ \"prompt\": { \"format\": \"messages\", \"messages\": [] } }\n\n// after\n{ \"prompt\": { \"format\": \"messages\", \"messages\": [ { \"role\": \"user\", \"content\": \"Hello\" } ] } }","handlingStrategy":"validation","validationCode":"const msgs = raw?.prompt?.messages\nif (!Array.isArray(msgs) || msgs.length === 0) { /* block import */ }\n// additionally check each entry has a known role","typeGuard":"const isMessageArray = (v: unknown): v is Array<{ role: string; content: unknown }> =>\n  Array.isArray(v) && v.length > 0 && v.every(m => isPlainObject(m) && typeof m.role === 'string')","tryCatchPattern":"catch (e) { if (e.message === 'Empty prompt.messages') showImportError('Conversation is empty or invalid'); else throw e }","preventionTips":["Validate roles against the importer's supported set before export","Never publish empty conversations","Unit-test normalizeImportedConversationMessages with real exports"],"tags":["prompt-garden","messages","empty-content","validation"],"backgroundTag":"empty-required-field","analyzedSha":"3e677b1d9f7e0493c142c175560531e7ae786dce","analyzedAt":"2026-08-27T21:29:16.709Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}