{"record":{"id":"d7550424d0d2f586","repo":"apify/crawlee","slug":"request-options-must-be-an-object-got-the-strin","errorCode":null,"errorMessage":"`Request` options must be an object, got the string '${options}'. Did you mean `new Request({ url })`?","messagePattern":"`Request` options must be an object, got the string '(.+?)'\\. Did you mean `new Request\\((.+?)\\)`\\?","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"packages/core/src/request.ts","lineNumber":159,"sourceCode":"     *\n     * All data stored in `userData` must be JSON-serializable.\n     * Storing non-serializable values (e.g. functions, symbols) may result in unexpected results.\n     */\n    userData: UserData = {} as UserData;\n\n    /**\n     * ISO datetime string that indicates the time when the request has been processed.\n     * Is `null` if the request has not been crawled yet.\n     */\n    handledAt?: string;\n\n    /**\n     * `Request` parameters including the URL, HTTP method and headers, and others.\n     */\n    constructor(options: RequestOptions<UserData>) {\n        // A bare URL is a common slip — point at the object form instead of a generic type error.\n        if (typeof options === 'string') {\n            throw new TypeError(\n                `\\`Request\\` options must be an object, got the string '${options}'. ` +\n                    'Did you mean `new Request({ url })`?',\n            );\n        }\n\n        parseArgument(options, schemas.anyObject, 'RequestOptions');\n        parseArgument(options, requestUrlSchema, 'RequestOptions');\n        // Full-shape validation is slow, because it checks all predicates\n        // even if the validated object has only 1 property.\n        // This custom validation loop iterates only over existing\n        // properties and speeds up the validation cca 3-fold.\n        keys(options).forEach((prop) => {\n            // skip url, because it is validated above\n            if (prop === 'url') {\n                return;\n            }\n\n            const schema = requestOptionalSchemas[prop as string];","sourceCodeStart":141,"sourceCodeEnd":177,"githubUrl":"https://github.com/apify/crawlee/blob/dbe57fb09ca607ad59dcf998f3925ef9ac3bb26c/packages/core/src/request.ts#L141-L177","documentation":"The Request constructor expects a RequestOptions object. Passing a bare string (a common slip where developers assume new Request('https://...') works) throws a TypeError with a hint pointing at the object form new Request({ url }).","triggerScenarios":"new Request('https://example.com') — passing a URL string directly instead of { url: 'https://example.com' }.","commonSituations":"Migrating from other HTTP libraries whose Request accepts a string; copy-pasted code from fetch-style APIs; TypeScript suppressed or JS code bypassing compile-time type errors.","solutions":["Wrap the URL in an object: new Request({ url })","If you have a Request-like value that may be a string, normalize it before construction","Enable TypeScript checking so the RequestOptions type error surfaces at compile time"],"exampleFix":"// before\nconst request = new Request('https://example.com');\n// after\nconst request = new Request({ url: 'https://example.com' });","handlingStrategy":"type-guard","validationCode":"if (typeof options === 'string') throw new TypeError('Use new Request({ url })');","typeGuard":"function isRequestOptions(o: unknown): o is RequestOptions {\n  return typeof o === 'object' && o !== null && 'url' in o;\n}","tryCatchPattern":"try {\n  return new Request(opts);\n} catch (err) {\n  if (err instanceof TypeError && err.message.includes('must be an object')) {\n    return new Request({ url: String(opts) });\n  }\n  throw err;\n}","preventionTips":["Always construct with the object form new Request({ url })","Let TypeScript check arguments instead of casting strings","Wrap string-to-Request conversion in a helper that normalizes input"],"tags":["typescript","api-misuse","request"],"backgroundTag":"invalid-constructor-argument","analyzedSha":"dbe57fb09ca607ad59dcf998f3925ef9ac3bb26c","analyzedAt":"2026-08-30T22:22:28.328Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}