laurent22/joplin · error · Error

${errorPrefix}: ${key} must be an array

Error message

${errorPrefix}: ${key} must be an array

What it means

Thrown inside `getReplacements` (used by `processOutputSettings`) when one of the replacement fields (`stringReplacements` or `regexReplacements`) is present but not an array. Each such field must be an array of `[pattern, replacement]` pairs.

Source

Thrown at packages/app-mobile/services/voiceTyping/whisper.ts:44

				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`);
			}

			const getReplacements = (key: string, value: unknown) => {
				if (!Array.isArray(value)) {
					throw new Error(`${errorPrefix}: ${key} must be an array`);
				}

				const results: [string, string][] = [];
				for (const replacement of value) {
					if (!Array.isArray(replacement)) {
						throw new Error(`${errorPrefix}: values for ${key} must be arrays`);
					}
					if (typeof replacement[0] !== 'string' || typeof replacement[1] !== 'string') {
						throw new Error(`${errorPrefix}: values for ${key} must be pairs of strings`);
					}

					results.push([replacement[0], replacement[1]]);
				}
				return results;
			};

			if ('stringReplacements' in json.output) {
				this.stringReplacements = getReplacements('stringReplacements', json.output.stringReplacements);

View on GitHub (pinned to 2654b33620)

Solutions

  1. Wrap the value in an array: `[ ["foo", "bar"] ]`.
  2. Re-download the model bundle.
  3. Schema-validate that replacement fields are arrays of string pairs.

Example fix

// before
"stringReplacements": ["foo", "bar"]

// after
"stringReplacements": [["foo", "bar"]]
Defensive patterns

Strategy: validation

Validate before calling

for (const key of ['stringReplacements', 'regexReplacements']) {
  const v = (config.output ?? {})[key];
  if (v !== undefined && !Array.isArray(v)) {
    throw new Error(`Whisper config: ${key} must be an array`);
  }
}

Type guard

const isReplacementArray = (v: unknown): v is unknown[] => Array.isArray(v);

Try / catch

null

Prevention

When it happens

Trigger: Config like `{ "output": { "stringReplacements": "foo" } }` where the field value is not an array. The interpolated `${key}` is the offending field name.

Common situations: Hand-edited config; misunderstanding the format and supplying a single pair instead of an array of pairs; migration typo.

Related errors


AI-assisted analysis of laurent22/joplin@2654b33620 (2026-08-12). Data as JSON: /api/errors/2eb174c67fac6b24. Report an issue: GitHub.