{"record":{"id":"c125ed6b43280b08","repo":"apify/crawlee","slug":"requestvalidationerror-label-result-issues","errorCode":null,"errorMessage":"RequestValidationError(label, result.issues)","messagePattern":"RequestValidationError\\(label, result\\.issues\\)","errorType":"validation","errorClass":"RequestValidationError","httpStatus":null,"severity":"error","filePath":"packages/core/src/router.ts","lineNumber":107,"sourceCode":"export async function validateUserData(\n    label: string | symbol,\n    schema: StandardSchemaV1,\n    userData: unknown,\n): Promise<Dictionary> {\n    const { label: _label, ...rest } = (userData ?? {}) as Dictionary;\n\n    // `label` is a Crawlee-managed key that lives inside `userData`, so validating it is opt-in: we validate\n    // without it first, letting schemas that don't describe it pass (including `.strict()` ones). A schema that\n    // *does* declare `label` reports an issue for the now-missing key — so we re-validate with it included,\n    // honouring the declaration. Unlike `userData.__crawlee`, `label` is enumerable, so schemas do see it.\n    let result = await schema['~standard'].validate(rest);\n\n    if (result.issues?.some(isLabelIssue)) {\n        result = await schema['~standard'].validate({ ...rest, label });\n    }\n\n    if (result.issues) {\n        throw new RequestValidationError(label, result.issues);\n    }\n\n    // Restore the label so it survives schemas that strip undeclared keys.\n    return { ...(result.value as Dictionary), label };\n}\n\n/**\n * The set of labels accepted by {@apilink Router.addHandler}. When the router declares a concrete\n * route map (e.g. `{ PRODUCT: ...; CATEGORY: ... }`), only those labels (plus symbols) are\n * allowed — unknown labels become a compile-time error. When the map is left open (the default\n * `Record<string, ...>`), any string or symbol label is accepted, preserving the original behaviour.\n */\nexport type RouterLabel<Routes extends Record<keyof Routes, Dictionary>> = string extends keyof Routes\n    ? string | symbol\n    : (keyof Routes & string) | symbol;\n\nexport interface RouterHandler<\n    Context extends RestrictedCrawlingContext = CrawlingContext,","sourceCodeStart":89,"sourceCodeEnd":125,"githubUrl":"https://github.com/apify/crawlee/blob/dbe57fb09ca607ad59dcf998f3925ef9ac3bb26c/packages/core/src/router.ts#L89-L125","documentation":"validateUserData runs the request's user data through the route's Standard Schema and throws RequestValidationError (including the label and the validation issues) when the data does not conform. It backs validateRequestUserData and validateRequest, so invalid userData is caught before a handler runs.","triggerScenarios":"Enqueuing or dispatching a request whose userData fails the schema declared for its label, e.g. missing required fields or wrong types in crawler.addRequests([...]) data.","commonSituations":"Changing a handler's expected userData schema without updating producers; JSON payloads from queues/APIs missing fields; label-specific schemas applied to requests created elsewhere.","solutions":["Read the issues on RequestValidationError and fix the userData to match the schema","Validate userData with the same schema at the point where requests are created","Add defaults/optional fields to the schema for legitimately optional data","Ensure the label is set correctly — the validator re-validates with the label when the label field itself fails"],"exampleFix":"// before\nawait crawler.addRequests([{ url, userData: { label: 'detail', id } }]);\n// after\nconst userData = detailSchema.parse({ label: 'detail', id });\nawait crawler.addRequests([{ url, userData }]);","handlingStrategy":"validation","validationCode":"const check = schema['~standard'].validate(userData);\nif ((await check).issues) throw new RequestValidationError(label, (await check).issues);","typeGuard":"function isValidUserData<T>(v: unknown, schema: StandardSchema<T>): v is T {\n  return !schema['~standard'].validate(v).issues;\n}","tryCatchPattern":"try {\n  await crawler.run(requests);\n} catch (err) {\n  if (err instanceof RequestValidationError) {\n    console.error(`Invalid userData for label ${err.label}:`, err.issues);\n  } else throw err;\n}","preventionTips":["Validate userData at creation time with the same schema the router uses","Keep producer and consumer schemas in a shared module","Include the label in userData explicitly and verify it against registered routes","Test enqueue -> handle round trips in CI"],"tags":["validation","schema","request"],"backgroundTag":"schema-validation-failed","analyzedSha":"dbe57fb09ca607ad59dcf998f3925ef9ac3bb26c","analyzedAt":"2026-08-30T22:22:28.328Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}