{"record":{"id":"eac2bd0c6241735a","repo":"can1357/oh-my-pi","slug":"cannot-choose-from-an-empty-header-profile-list","errorCode":null,"errorMessage":"Cannot choose from an empty header profile list","messagePattern":"Cannot choose from an empty header profile list","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/utils/src/headers.ts","lineNumber":61,"sourceCode":"\tbrowserListQuery: \"\",\n\toperatingSystems: [\"windows\", \"macos\", \"linux\"],\n\tdevices: [\"desktop\"],\n\tlocales: [\"en-US\", \"en\"],\n\thttpVersion: \"2\",\n\tstrict: false,\n};\n\nconst VERSIONS: Readonly<Record<BrowserName, readonly number[]>> = {\n\tchrome: [149, 150, 151],\n\tfirefox: [147, 148, 149],\n\tsafari: [26, 26.1, 26.2],\n};\n\nfunction pick<T>(values: readonly T[], rng: () => number): T {\n\tconst random = rng();\n\tconst index = Math.min(values.length - 1, Math.max(0, Math.floor(random * values.length)));\n\tconst value = values[index];\n\tif (value === undefined) throw new Error(\"Cannot choose from an empty header profile list\");\n\treturn value;\n}\n\nfunction formatLocales(locales: readonly string[]): string {\n\treturn locales\n\t\t.slice(0, 10)\n\t\t.map((locale, index) => {\n\t\t\tif (index === 0) return locale;\n\t\t\tconst quality = Math.max(0.1, 1 - index / 10).toFixed(1);\n\t\t\treturn `${locale};q=${quality}`;\n\t\t})\n\t\t.join(\",\");\n}\n\nfunction makeUserAgent(browser: BrowserName, operatingSystem: OperatingSystem, version: number): string {\n\tif (browser === \"safari\") {\n\t\treturn `Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/${version.toFixed(1)} Safari/605.1.15`;\n\t}","sourceCodeStart":43,"sourceCodeEnd":79,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/utils/src/headers.ts#L43-L79","documentation":"pick() selects a random element from a profile list using the injected RNG. Despite clamping the index to [0, length-1], an empty array yields values[0] === undefined, so it throws this Error. It is an internal invariant guard: callers must never pass an empty candidate list (empty browsers, operatingSystems, or unknown browser with no VERSIONS entry).","triggerScenarios":"Calling getHeaders with an empty candidates array reached via makeProfile in non-strict mode... practically: passing browsers: [] with a candidate list that ends up empty, or an empty locales/versions list reaching pick; also a buggy custom rng returning NaN (index becomes NaN → values[NaN] undefined).","commonSituations":"Constructing HeaderGenerator with browsers: [] and then calling getHeaders in a path where the chrome/windows fallback does not apply; passing a broken rng (returns NaN or out-of-range values) in tests.","solutions":["Ensure options.browsers is non-empty when constructing/calling","Check that custom rng implementations return finite values in [0,1)","Verify VERSIONS covers any browser name you pass (only chrome/firefox/safari supported)","Catch and log to detect misconfigured option propagation"],"exampleFix":"// before\nnew HeaderGenerator({ browsers: [] }).getHeaders();\n// after\nnew HeaderGenerator({ browsers: [\"chrome\"] }).getHeaders(); // or omit to use defaults","handlingStrategy":"validation","validationCode":"function assertNonEmpty<T>(values: readonly T[], label: string): readonly T[] {\n  if (values.length === 0) throw new Error(`${label} must not be empty`);\n  return values;\n}\nconst browsers = assertNonEmpty(options.browsers ?? [\"chrome\"], \"browsers\");","typeGuard":"function isNonEmpty<T>(values: readonly T[] | undefined): values is readonly [T, ...T[]] {\n  return Array.isArray(values) && values.length > 0;\n}","tryCatchPattern":"try {\n  return generator.getHeaders();\n} catch (err) {\n  if (err instanceof Error && err.message.includes(\"empty header profile list\")) {\n    return fallbackHeaders; // or re-construct with default options\n  }\n  throw err;\n}","preventionTips":["Never pass empty browsers/operatingSystems arrays","Only use the three supported browsers (chrome/firefox/safari)","Validate custom rng implementations return finite values in [0,1)","Validate option-bearing config files before constructing HeaderGenerator"],"tags":["headers","validation","empty-array"],"backgroundTag":"empty-list-selection","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}