{"record":{"id":"64446323f1a16ee6","repo":"sveltejs/kit","slug":"async-param-matchers-are-not-supported","errorCode":null,"errorMessage":"Async param matchers are not supported","messagePattern":"Async param matchers are not supported","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/kit/src/utils/routing.js","lineNumber":147,"sourceCode":" * don't affect the path (i.e. groups). The root route is represented by `/`\n * and will be returned as `['']`.\n * @param {string} route\n * @returns string[]\n */\nexport function get_route_segments(route) {\n\treturn route.slice(1).split('/').filter(affects_path);\n}\n\n/**\n * @param {ParamMatcher} matcher\n * @param {string} value\n * @returns {{ success: true, value: any } | { success: false }}\n */\nfunction run_matcher(matcher, value) {\n\tconst result = matcher['~standard'].validate(value);\n\n\tif (result instanceof Promise) {\n\t\tthrow new Error('Async param matchers are not supported');\n\t}\n\n\tif (result.issues) {\n\t\treturn { success: false };\n\t}\n\n\tconst parsed = result.value;\n\n\tif (\n\t\ttypeof parsed !== 'string' &&\n\t\ttypeof parsed !== 'number' &&\n\t\ttypeof parsed !== 'boolean' &&\n\t\ttypeof parsed !== 'bigint'\n\t) {\n\t\tthrow new Error('Param matcher must return a string, number, boolean, or bigint');\n\t}\n\n\treturn { success: true, value: parsed };","sourceCodeStart":129,"sourceCodeEnd":165,"githubUrl":"https://github.com/sveltejs/kit/blob/03f1687fe612ce3d2d9131139b5b188d9cf90c64/packages/kit/src/utils/routing.js#L129-L165","documentation":"Param matchers in SvelteKit use the Standard Schema `validate` API. `run_matcher` requires validation to be synchronous; if a matcher's `~standard.validate` returns a Promise (async validation), routing cannot proceed because param matching happens synchronously during route resolution. The library therefore rejects async matchers outright.","triggerScenarios":"A matcher defined with `defineParams` uses an async Standard Schema implementation, or `run_matcher` is called with a matcher whose `validate(value)` returns a Promise instead of a plain result object.","commonSituations":"Writing a custom Standard Schema adapter with an `async validate()` method; using a schema library configured in async mode (e.g. async refinements/transforms in Valibot/Zod async APIs) for param matchers; upgrading a schema library so a previously sync validator became async.","solutions":["Rewrite the matcher's `validate` so it returns the result synchronously (no `async`, no awaited refinements)","Move any async work (e.g. DB lookups) out of the matcher into the route's load function and validate there","Use a sync-only schema API for the matcher (e.g. Valibot sync parsers, Zod `.safeParse` instead of async paths)"],"exampleFix":"// before\nconst matcher = defineMatcher({\n\t'~standard': {\n\t\tasync validate(value) {\n\t\t\treturn (await existsInDb(value)) ? { value } : { issues: [{ message: 'nope' }] };\n\t\t}\n\t}\n});\n// after\nconst matcher = defineMatcher({\n\t'~standard': {\n\t\tvalidate(value) {\n\t\t\treturn /^[a-z0-9-]+$/.test(value) ? { value } : { issues: [{ message: 'invalid' }] };\n\t\t}\n\t}\n});","handlingStrategy":"try-catch","validationCode":"const result = matcher['~standard'].validate('test-value');\nif (result instanceof Promise) {\n\tthrow new Error('Matcher must be synchronous');\n}","typeGuard":"function isSyncMatcher(matcher) {\n\tconst r = matcher['~standard'].validate('probe');\n\treturn !(r instanceof Promise);\n}","tryCatchPattern":"try {\n\tconst outcome = runMatcher(matcher, value);\n} catch (e) {\n\tif (e.message === 'Async param matchers are not supported') {\n\t\t// replace matcher with a synchronous schema\n\t}\n\tthrow e;\n}","preventionTips":["Never mark matcher validate() as async","Avoid async refinements/transforms from schema libraries in matchers","Probe matchers with a sync validation check in tests"],"tags":["params","matcher","standard-schema","async"],"backgroundTag":"async-validator-not-supported","analyzedSha":"03f1687fe612ce3d2d9131139b5b188d9cf90c64","analyzedAt":"2026-09-02T02:01:50.504Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T06:17:21.866Z"}