{"record":{"id":"1a49facc3d47b5f3","repo":"linshenkx/prompt-optimizer","slug":"missing-optimizertarget-submodekey","errorCode":null,"errorMessage":"Missing optimizerTarget.subModeKey","messagePattern":"Missing optimizerTarget\\.subModeKey","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/ui/src/composables/app/useAppPromptGardenImport.ts","lineNumber":542,"sourceCode":"\n  const parseV1 = (data: unknown): FetchedPrompt => {\n    if (!isPlainObject(data)) {\n      throw new Error('Garden response must be a JSON object')\n    }\n    if (data.schema !== 'prompt-garden.prompt.v1') {\n      throw new Error('Unsupported Garden response schema')\n    }\n    if (data.schemaVersion !== 1) {\n      throw new Error('Unsupported Garden response schemaVersion')\n    }\n\n    const optimizerTarget = isPlainObject(data.optimizerTarget) ? data.optimizerTarget : null\n    const optimizerTargetKey =\n      optimizerTarget && typeof optimizerTarget.subModeKey === 'string'\n        ? optimizerTarget.subModeKey.trim()\n        : ''\n    if (!optimizerTargetKey) {\n      throw new Error('Missing optimizerTarget.subModeKey')\n    }\n\n    const prompt = isPlainObject(data.prompt) ? data.prompt : null\n    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","sourceCodeStart":524,"sourceCodeEnd":560,"githubUrl":"https://github.com/linshenkx/prompt-optimizer/blob/3e677b1d9f7e0493c142c175560531e7ae786dce/packages/ui/src/composables/app/useAppPromptGardenImport.ts#L524-L560","documentation":"After schema checks pass, the importer requires routing metadata: data.optimizerTarget.subModeKey must exist, be a string, and be non-empty after trimming. This key tells the importer which optimizer sub-mode the prompt targets; without it the imported prompt cannot be routed.","triggerScenarios":"optimizerTarget is missing, not a plain object, subModeKey is absent/null/number, or is a whitespace-only string after trim().","commonSituations":"Prompts exported without an optimizer target selected; older exports that predate the optimizerTarget field; upstream data corruption; fixture prompts copied without the routing block.","solutions":["Add an optimizerTarget object with a non-empty string subModeKey to the payload (e.g. {\"optimizerTarget\":{\"subModeKey\":\"default\"}})","Verify the export flow on the Garden side actually captures the sub-mode key","If the key is genuinely optional for your use case, patch parseV1 to fall back to a default instead of throwing"],"exampleFix":"// before\n{ \"prompt\": { ... }, \"optimizerTarget\": {} }\n\n// after\n{ \"prompt\": { ... }, \"optimizerTarget\": { \"subModeKey\": \"quality\" } }","handlingStrategy":"type-guard","validationCode":"const key = raw?.optimizerTarget?.subModeKey\nif (typeof key !== 'string' || !key.trim()) { /* block import with clear message */ }","typeGuard":"const hasOptimizerTarget = (d: unknown): d is { optimizerTarget: { subModeKey: string } } =>\n  isPlainObject(d) && isPlainObject(d.optimizerTarget) && typeof d.optimizerTarget.subModeKey === 'string' && d.optimizerTarget.subModeKey.trim() !== ''","tryCatchPattern":"catch (e) { if (e.message === 'Missing optimizerTarget.subModeKey') promptUserToPickSubMode(); else throw e }","preventionTips":["Require sub-mode selection before exporting prompts","Validate exports on the Garden side before publishing","Include optimizerTarget in test fixtures"],"tags":["prompt-garden","required-field","validation"],"backgroundTag":"missing-required-field","analyzedSha":"3e677b1d9f7e0493c142c175560531e7ae786dce","analyzedAt":"2026-08-27T21:29:16.709Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}