{"record":{"id":"306b2c05cf01cf1d","repo":"linshenkx/prompt-optimizer","slug":"missing-variables","errorCode":null,"errorMessage":"Missing variables","messagePattern":"Missing variables","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/ui/src/composables/app/useAppPromptGardenImport.ts","lineNumber":570,"sourceCode":"\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 => {\n        if (!isPlainObject(v)) return null\n        const name = typeof v.name === 'string' ? v.name.trim() : ''\n        if (!isValidVariableName(name)) return null\n\n        const type =\n          v.type === 'string' || v.type === 'number' || v.type === 'boolean' || v.type === 'enum'","sourceCodeStart":552,"sourceCodeEnd":588,"githubUrl":"https://github.com/linshenkx/prompt-optimizer/blob/3e677b1d9f7e0493c142c175560531e7ae786dce/packages/ui/src/composables/app/useAppPromptGardenImport.ts#L552-L588","documentation":"The v1 schema requires a top-level `variables` array (which may legitimately be empty). This error means data.variables is not an Array at all — it is missing, null, or an object. Each entry is later mapped to {name, defaultValue}, so the array invariant is enforced before mapping.","triggerScenarios":"data.variables is undefined, null, a plain object (e.g. a keyed map of variables), or a string.","commonSituations":"Exports that serialize variables as an object map ({\"var1\": {...}}) instead of an array; older/newer export versions; hand-written fixtures omitting the field because it looked optional.","solutions":["Ensure the payload includes \"variables\": [] (empty array) at minimum","If variables arrive as an object map, convert with Object.values(variables) before import or fix the exporter","Validate the full payload shape against the v1 schema before handing it to parseV1"],"exampleFix":"// before\n{ ...payload, \"variables\": { \"topic\": { \"defaultValue\": \"x\" } } }\n\n// after\n{ ...payload, \"variables\": [ { \"name\": \"topic\", \"defaultValue\": \"x\" } ] }","handlingStrategy":"validation","validationCode":"if (!Array.isArray(raw?.variables)) { raw.variables = [] /* or reject */ }","typeGuard":"const hasVariablesArray = (d: unknown): boolean => isPlainObject(d) && Array.isArray(d.variables)","tryCatchPattern":"catch (e) { if (e.message === 'Missing variables') { payload.variables = []; retryImport(payload); } else throw e }","preventionTips":["Always emit \"variables\": [] in exports","Prefer arrays over keyed maps for list data in wire formats","Schema-validate exports in CI"],"tags":["prompt-garden","validation","variables"],"backgroundTag":"schema-validation-failed","analyzedSha":"3e677b1d9f7e0493c142c175560531e7ae786dce","analyzedAt":"2026-08-27T21:29:16.709Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}