redis/node-redis · error · Error

Invalid JSON configuration: ${error}

Error message

Invalid JSON configuration: ${error}

What it means

loadFromJson wraps JSON.parse and rethrows with this message when the supplied string is not valid JSON. It is used by the CAE test-utils endpoint loader to parse a RedisEndpointsConfig (a record of named endpoints). The underlying SyntaxError (including the token/position reported by the engine) is interpolated into the message.

Source

Thrown at packages/test-utils/lib/cae-client-testing.ts:16

import { readFile } from 'node:fs/promises';

interface RawRedisEndpoint {
  username?: string;
  password?: string;
  tls: boolean;
  endpoints: string[];
}

export type RedisEndpointsConfig = Record<string, RawRedisEndpoint>;

export function loadFromJson(jsonString: string): RedisEndpointsConfig {
  try {
    return JSON.parse(jsonString) as RedisEndpointsConfig;
  } catch (error) {
    throw new Error(`Invalid JSON configuration: ${error}`);
  }
}

export async function loadFromFile(path: string): Promise<RedisEndpointsConfig> {
  try {
    const configFile = await readFile(path, 'utf-8');
    return loadFromJson(configFile);
  } catch (error) {
    if (error instanceof Error && 'code' in error && error.code === 'ENOENT') {
      throw new Error(`Config file not found at path: ${path}`);
    }
    throw error;
  }
}

View on GitHub (pinned to 90fd0652bc)

Solutions

  1. Paste the JSON into a validator/linter to find the exact syntax location
  2. Run JSON.parse(snippet) in isolation in a REPL to surface the precise position from the engine
  3. Use loadFromFile(path) instead so you also get the clearer ENOENT path for missing files

Example fix

// before — trailing comma
'{ "tls": false, "endpoints": ["host:6379",], }'

// after — valid JSON
'{ "tls": false, "endpoints": ["host:6379"] }'
Defensive patterns

Strategy: validation

Validate before calling

function tryParseRedisConfig(jsonString: string): RedisEndpointsConfig {
  try {
    const parsed = JSON.parse(jsonString);
    if (parsed === null || typeof parsed !== 'object') {
      throw new Error('config must be a JSON object');
    }
    return parsed as RedisEndpointsConfig;
  } catch (e) {
    throw new Error(`Invalid JSON configuration: ${e instanceof Error ? e.message : e}`);
  }
}

Type guard

function isRedisEndpointsConfig(v: unknown): v is Record<string, RawRedisEndpoint> {
  if (typeof v !== 'object' || v === null) return false;
  for (const endpoint of Object.values(v)) {
    if (typeof endpoint !== 'object' || endpoint === null) return false;
    if (typeof endpoint.tls !== 'boolean') return false;
    if (!Array.isArray(endpoint.endpoints) || !endpoint.endpoints.every((e: unknown) => typeof e === 'string')) return false;
  }
  return true;
}

Try / catch

try {
  const cfg = loadFromJson(raw);
} catch (e) {
  if (e instanceof Error && e.message.startsWith('Invalid JSON configuration')) {
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling loadFromJson(jsonString) with a string containing a JSON syntax error: trailing comma, single-quoted keys, unquoted strings, a BOM, or an empty string.

Common situations: Hand-editing a JSON config and introducing a typo; copy-pasting from a rich-text editor that converts quotes to smart quotes; passing a path string instead of file contents; encoding artifacts.

Understand the failure class

Related errors


AI-assisted analysis of redis/node-redis@90fd0652bc (2026-08-11). Data as JSON: /api/errors/d963d372ac8640a7. Report an issue: GitHub.