laurent22/joplin · error · Error
Whisper config is not an object
Error message
Whisper config is not an object
What it means
Thrown by the `WhisperConfig` constructor when the parsed JSON config passed to it is not an object (e.g. it is a number, string, array, or null). This is the top-level shape validation before reading any fields like `prompts` or `output`.
Source
Thrown at packages/app-mobile/services/voiceTyping/whisper.ts:21
import Logger from '@joplin/utils/Logger';
import { rtrimSlashes } from '@joplin/utils/path';
import { dirname, join } from 'path';
import { openSession, test as testWhisper, Session as WhisperSession } from '@joplin/whisper-voice-typing';
import { SpeechToTextCallbacks, VoiceTypingProvider, VoiceTypingSession } from './VoiceTyping';
import { languageCodeOnly, stringByLocale } from '@joplin/lib/locale';
import { Platform } from 'react-native';
const logger = Logger.create('voiceTyping/whisper');
class WhisperConfig {
public prompts: Map<string, string> = new Map();
public supportsShortAudioCtx = false;
public stringReplacements: [string, string][] = [];
public regexReplacements: [RegExp, string][] = [];
public constructor(json: unknown) {
const errorPrefix = 'Whisper config';
if (typeof json !== 'object') throw new Error('Whisper config is not an object');
const processPrompts = () => {
if (!('prompts' in json)) return;
if (typeof json.prompts !== 'object') {
throw new Error(`${errorPrefix}: Field "prompts" is not an object`);
}
for (const [key, value] of Object.entries(json.prompts)) {
if (typeof value !== 'string') {
throw new Error(`${errorPrefix}: Value for key ${key} is ${typeof value}, not string.`);
}
this.prompts.set(key, value);
}
};
const processOutputSettings = () => {
if (!('output' in json)) return;
if (typeof json.output !== 'object') {
throw new Error(`${errorPrefix}: Field "output" is not an object`);View on GitHub (pinned to 2654b33620)
Solutions
- Validate the parsed config shape before constructing: `if (!json || typeof json !== 'object' || Array.isArray(json)) ...`.
- Re-download the model bundle to restore a known-good `config.json`.
- If shipping custom configs, schema-validate against the expected WhisperConfig shape at authoring time.
Example fix
// before
if (typeof json !== 'object') throw new Error('Whisper config is not an object');
// after
if (!json || typeof json !== 'object' || Array.isArray(json)) {
throw new Error('Whisper config is not an object');
} Defensive patterns
Strategy: type-guard
Validate before calling
const isConfigObject = (json: unknown): json is Record<string, unknown> =>
!!json && typeof json === 'object' && !Array.isArray(json);
if (!isConfigObject(parsed)) {
throw new Error('Whisper config file is malformed at the root');
} Type guard
const isWhisperConfigRoot = (json: unknown): json is Record<string, unknown> => json !== null && typeof json === 'object' && !Array.isArray(json);
Try / catch
null
Prevention
- Schema-validate config.json before constructing WhisperConfig.
- Treat null as invalid even though typeof null === 'object'.
- Re-download the model bundle if config validation fails.
When it happens
Trigger: Constructing `new WhisperConfig(json)` where `json` came from `JSON.parse(...)` of a `config.json` file whose root value is a primitive, an array, or `null`. `typeof null === 'object'` is a footgun but `null` will pass this check and fail later — arrays and primitives are caught here.
Common situations: Corrupted or hand-edited `config.json` next to a downloaded whisper model; an empty file parsed to a non-object; a model bundle shipping a malformed config.
Related errors
- ${errorPrefix}: Field "prompts" is not an object
- ${errorPrefix}: Value for key ${key} is ${typeof value}, not
- ${errorPrefix}: Field "output" is not an object
- ${errorPrefix}: ${key} must be an array
- ${errorPrefix}: values for ${key} must be arrays
AI-assisted analysis of laurent22/joplin@2654b33620 (2026-08-12).
Data as JSON: /api/errors/25a868052796c400.
Report an issue: GitHub.