{"record":{"id":"0164907dffcbaf3f","repo":"laurent22/joplin","slug":"errorprefix-field-prompts-is-not-an-object","errorCode":null,"errorMessage":"${errorPrefix}: Field \"prompts\" is not an object","messagePattern":"(.+?): Field \"prompts\" is not an object","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/app-mobile/services/voiceTyping/whisper.ts","lineNumber":26,"sourceCode":"import { languageCodeOnly, stringByLocale } from '@joplin/lib/locale';\nimport { Platform } from 'react-native';\n\nconst logger = Logger.create('voiceTyping/whisper');\n\nclass WhisperConfig {\n\tpublic prompts: Map<string, string> = new Map();\n\tpublic supportsShortAudioCtx = false;\n\tpublic stringReplacements: [string, string][] = [];\n\tpublic regexReplacements: [RegExp, string][] = [];\n\n\tpublic constructor(json: unknown) {\n\t\tconst errorPrefix = 'Whisper config';\n\t\tif (typeof json !== 'object') throw new Error('Whisper config is not an object');\n\n\t\tconst processPrompts = () => {\n\t\t\tif (!('prompts' in json)) return;\n\t\t\tif (typeof json.prompts !== 'object') {\n\t\t\t\tthrow new Error(`${errorPrefix}: Field \"prompts\" is not an object`);\n\t\t\t}\n\n\t\t\tfor (const [key, value] of Object.entries(json.prompts)) {\n\t\t\t\tif (typeof value !== 'string') {\n\t\t\t\t\tthrow new Error(`${errorPrefix}: Value for key ${key} is ${typeof value}, not string.`);\n\t\t\t\t}\n\t\t\t\tthis.prompts.set(key, value);\n\t\t\t}\n\t\t};\n\t\tconst processOutputSettings = () => {\n\t\t\tif (!('output' in json)) return;\n\t\t\tif (typeof json.output !== 'object') {\n\t\t\t\tthrow new Error(`${errorPrefix}: Field \"output\" is not an object`);\n\t\t\t}\n\n\t\t\tconst getReplacements = (key: string, value: unknown) => {\n\t\t\t\tif (!Array.isArray(value)) {\n\t\t\t\t\tthrow new Error(`${errorPrefix}: ${key} must be an array`);","sourceCodeStart":8,"sourceCodeEnd":44,"githubUrl":"https://github.com/laurent22/joplin/blob/2654b33620775080d1d59c552259d41e33dad3d2/packages/app-mobile/services/voiceTyping/whisper.ts#L8-L44","documentation":"Thrown by `WhisperConfig.processPrompts` when the `prompts` field exists in the config but is not an object (e.g. a string, number, or array). Prompts are expected to be a map of locale → string.","triggerScenarios":"Parsed `config.json` contains `\"prompts\": \"...\"` or `\"prompts\": [...]` or any non-object value. Triggered after the top-level object check passes and `processPrompts` runs.","commonSituations":"Hand-edited config with `prompts` set to a string by mistake; older format that used an array; migration/typo when authoring the model bundle config.","solutions":["Edit `config.json` so `prompts` is an object: `{ \"en\": \"...\", \"fr\": \"...\" }`.","Re-download the model to restore the shipped config.","If writing configs programmatically, schema-validate `prompts` is `Record<string,string>` before write."],"exampleFix":"// before\n\"prompts\": \"en-us prompt text\"\n\n// after\n\"prompts\": { \"en-us\": \"en-us prompt text\" }","handlingStrategy":"validation","validationCode":"if ('prompts' in config && (typeof config.prompts !== 'object' || config.prompts === null || Array.isArray(config.prompts))) {\n  throw new Error('Whisper config: prompts must be an object');\n}","typeGuard":"const isPromptsObject = (v: unknown): v is Record<string, unknown> =>\n  !!v && typeof v === 'object' && !Array.isArray(v);","tryCatchPattern":"null","preventionTips":["Author prompts as { locale: string } maps.","Schema-validate before shipping or loading the config.","Re-download the bundle on validation failure."],"tags":["voice-typing","whisper","config","validation"],"backgroundTag":null,"analyzedSha":"2654b33620775080d1d59c552259d41e33dad3d2","analyzedAt":"2026-08-12T14:26:46.263Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}