{"id":"f706b9847a2b4add","repo":"sindresorhus/got","slug":"unexpected-option-key","errorCode":null,"errorMessage":"Unexpected option: ${key}","messagePattern":"Unexpected option: (.+?)","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"source/core/options.ts","lineNumber":1712,"sourceCode":"\t\t}\n\n\t\toptions = cloneRaw(options);\n\n\t\tinit(this, options, this);\n\t\tinit(options, options, this);\n\n\t\tthis.#merging = true;\n\n\t\ttry {\n\t\t\tlet push = false;\n\n\t\t\tfor (const key of Object.keys(options)) {\n\t\t\t\tif (nonMergeableKeys.has(key)) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tif (!(key in this)) {\n\t\t\t\t\tthrow new Error(`Unexpected option: ${key}`);\n\t\t\t\t}\n\n\t\t\t\t// @ts-expect-error Type 'unknown' is not assignable to type 'never'.\n\t\t\t\tconst value = options[key as keyof Options];\n\t\t\t\tif (value === undefined) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// @ts-expect-error Type 'unknown' is not assignable to type 'never'.\n\t\t\t\tthis[key as keyof Options] = value;\n\n\t\t\t\tpush = true;\n\t\t\t}\n\n\t\t\tif (push) {\n\t\t\t\tthis.#init.push(options);\n\t\t\t}\n\t\t} finally {","sourceCodeStart":1694,"sourceCodeEnd":1730,"githubUrl":"https://github.com/sindresorhus/got/blob/e3924aa1e53a6ca3eb93a43618ce532442a89b40/source/core/options.ts#L1694-L1730","documentation":"Thrown by `Options.merge()` when the merged options object contains a top-level key that is not a known Options property (and not in the `nonMergeableKeys` set: mutableDefaults, handlers, url, preserveHooks, isStream, __proto__). Got validates keys against its own schema to surface typos and unsupported options early instead of silently ignoring them.","triggerScenarios":"Calling `got(url, {timout: 5000})` (typo), `got(url, {baseUrl: '...'})` (the option is named `prefixUrl`), or any call where the options object has a key that is not a real Options setter. Also triggered by `got.extend({...})` with the same kind of unknown key.","commonSituations":"Migrating from `request`/`axios` (`baseURL`, `proxy` object shapes), autocomplete-induced typos, copy-pasting options from another HTTP library, or upgrading Got versions where an option was renamed.","solutions":["Check the error message for the offending `${key}` and compare against the Got options docs (most often it is a rename like `baseUrl`->`prefixUrl`, `searchParameters`->`searchParams`).","Fix the typo/rename in your options object.","If you need to pass custom data, store it under the `context` option instead of an unknown top-level key."],"exampleFix":"// before\nawait got(url, {timout: {request: 5000}});\n// after\nawait got(url, {timeout: {request: 5000}});","handlingStrategy":"validation","validationCode":"import got from 'got';\nconst knownKeys = new Set(Object.getOwnPropertyNames(got.extend({}).defaults?.options ?? {}).concat(['method','headers','timeout','url','prefixUrl']));\nfunction validateOptions(options) {\n  for (const key of Object.keys(options ?? {})) {\n    if (!knownKeys.has(key)) throw new Error(`Unknown Got option: ${key}`);\n  }\n}","typeGuard":"// Got ships TypeScript types; rely on the compiler:\nimport type {OptionsInit} from 'got';\nfunction isOptionsInit(o: unknown): o is OptionsInit {\n  return typeof o === 'object' && o !== null;\n}","tryCatchPattern":"try { await got(url, opts); }\ncatch (error) {\n  if (error instanceof Error && error.message.startsWith('Unexpected option:')) {\n    const key = error.message.split(': ')[1];\n    delete opts[key];\n    return got(url, opts);\n  }\n  throw error;\n}","preventionTips":["Keep TypeScript strict so unknown keys are compile errors.","Centralize all Got option construction in one helper and lint for known keys.","When migrating from another lib, map option names explicitly rather than spreading."],"tags":["options","merge","typo","validation","config"],"analyzedSha":"e3924aa1e53a6ca3eb93a43618ce532442a89b40","analyzedAt":"2026-08-03T19:22:24.770Z","schemaVersion":2}