can1357/oh-my-pi · error · Error

Only desktop browser profiles are available

Error message

Only desktop browser profiles are available

What it means

HeaderGenerator only implements desktop browser profiles, so its devices option only accepts 'desktop'. If strict mode is enabled and the (merged) options contain any non-desktop device — e.g. 'mobile' or 'tablet', perhaps from configs written against the original header-generator package — the constructor throws this Error immediately.

Source

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

	const version = pick(VERSIONS[candidate.browser], rng);
	return {
		...candidate,
		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",

View on GitHub (pinned to 9690622007)

Solutions

  1. Remove non-desktop values from the devices array
  2. Set strict: false to tolerate the extra device values (they are then ignored)
  3. Drop the devices option entirely (desktop is the default)

Example fix

// before
new HeaderGenerator({ strict: true, devices: ["desktop", "mobile"] });
// after
new HeaderGenerator({ strict: true, devices: ["desktop"] });
Defensive patterns

Strategy: validation

Validate before calling

const devices = options.devices ?? ["desktop"];
if (options.strict && devices.some(d => d !== "desktop")) {
  throw new Error("this generator supports desktop devices only");
}

Type guard

function isDesktopOnly(devices: readonly string[]): boolean {
  return devices.every(d => d === "desktop");
}

Try / catch

try {
  return new HeaderGenerator(opts);
} catch (err) {
  if (err instanceof Error && err.message === "Only desktop browser profiles are available") {
    return new HeaderGenerator({ ...opts, devices: ["desktop"] });
  }
  throw err;
}

Prevention

When it happens

Trigger: new HeaderGenerator({ strict: true, devices: ['mobile'] }) or passing a devices array read from older header-generator config containing 'mobile'/'tablet'. Note DEFAULT_OPTIONS merge means a per-call getHeaders({ devices: [...] }) with strict also flows into makeProfile path, but the constructor check fires on constructor options.

Common situations: Migrating from apify/header-generator whose options include mobile/tablet device classes; config files copied from other projects with devices: ['desktop','mobile'].

Related errors


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