can1357/oh-my-pi · error · Error

At least one locale is required

Error message

At least one locale is required

What it means

In strict mode the constructor requires a non-empty locales array, because Accept-Language generation needs at least one locale. If options.locales resolves to [] (explicitly passed empty array, since defaults provide ['en-US','en']) and strict is true, the constructor throws this Error at construction time.

Source

Thrown at packages/utils/src/headers.ts:129

		version,
		userAgent: makeUserAgent(candidate.browser, candidate.operatingSystem, version),
	};
}

/** Generates coherent modern desktop browser navigation headers. */
export class HeaderGenerator {
	#options: ResolvedOptions;
	#rng: () => number;

	/** Creates a generator with reusable constraints and an optionally injectable RNG. */
	constructor(options: Partial<HeaderGeneratorOptions> = {}) {
		this.#rng = options.rng ?? Math.random;
		this.#options = { ...DEFAULT_OPTIONS, ...options };
		if (this.#options.devices.some(device => device !== "desktop") && this.#options.strict) {
			throw new Error("Only desktop browser profiles are available");
		}
		if (this.#options.locales.length === 0 && this.#options.strict) {
			throw new Error("At least one locale is required");
		}
	}

	/** Generates one header set, applying per-call constraints and request overrides. */
	getHeaders(options: Partial<HeaderGeneratorOptions> = {}, overrides: Headers = {}): Headers {
		const resolved = { ...this.#options, ...options };
		const rng = options.rng ?? this.#rng;
		const profile = makeProfile(resolved, rng);
		const headers: Headers = {
			accept:
				profile.browser === "chrome"
					? "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7"
					: "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
			"user-agent": profile.userAgent,
			"accept-encoding": profile.browser === "safari" ? "gzip, deflate, br" : "gzip, deflate, br, zstd",
			"accept-language": formatLocales(resolved.locales.length > 0 ? resolved.locales : DEFAULT_OPTIONS.locales),
			"upgrade-insecure-requests": "1",
			"sec-fetch-dest": "document",

View on GitHub (pinned to 9690622007)

Solutions

  1. Provide at least one locale, e.g. locales: ['en-US']
  2. Set strict: false — getHeaders then falls back to default ['en-US','en'] locales
  3. Drop the locales option to use defaults

Example fix

// before
new HeaderGenerator({ strict: true, locales: [] });
// after
new HeaderGenerator({ strict: true, locales: ["en-US"] });
Defensive patterns

Strategy: validation

Validate before calling

const locales = options.locales ?? ["en-US", "en"];
if (options.strict && locales.length === 0) {
  throw new Error("locales must not be empty in strict mode");
}

Type guard

function hasLocale(locales: readonly string[] | undefined): boolean {
  return Array.isArray(locales) && locales.length > 0;
}

Try / catch

try {
  return new HeaderGenerator(opts);
} catch (err) {
  if (err instanceof Error && err.message === "At least one locale is required") {
    return new HeaderGenerator({ ...opts, locales: ["en-US"] });
  }
  throw err;
}

Prevention

When it happens

Trigger: new HeaderGenerator({ strict: true, locales: [] }); or merging options where locales is overwritten with an empty array from config/JSON input while strict is enabled.

Common situations: Empty locales field in a settings file; spreading user options over defaults where locales: [] was explicitly serialized and strict: true set for reproducibility.

Related errors


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/98623a8e15e07320. Report an issue: GitHub.