{"record":{"id":"d708654a384b28fd","repo":"DioxusLabs/dioxus","slug":"wildcard-path-param-must-be-the-last-path-param","errorCode":null,"errorMessage":"wildcard path param must be the last path param","messagePattern":"wildcard path param must be the last path param","errorType":"validation","errorClass":"syn::Error","httpStatus":null,"severity":"error","filePath":"packages/fullstack-macro/src/lib.rs","lineNumber":1004,"sourceCode":"            return Err(syn::Error::new(span, \"expected path to start with '/'\"));\n        }\n        let path = path.strip_prefix('/').unwrap();\n\n        let mut path_params = Vec::new();\n\n        for path_param in path.split('/') {\n            path_params.push((\n                Slash(span),\n                PathParam::new(path_param, span, Box::new(parse_quote!(())))?,\n            ));\n        }\n\n        let path_param_len = path_params.len();\n        for (i, (_slash, path_param)) in path_params.iter().enumerate() {\n            match path_param {\n                PathParam::WildCard(_, _, _, _, _, _) => {\n                    if i != path_param_len - 1 {\n                        return Err(syn::Error::new(\n                            span,\n                            \"wildcard path param must be the last path param\",\n                        ));\n                    }\n                }\n                PathParam::Capture(_, _, _, _, _) => (),\n                PathParam::Static(lit) => {\n                    if lit.value() == \"*\" && i != path_param_len - 1 {\n                        return Err(syn::Error::new(\n                            span,\n                            \"wildcard path param must be the last path param\",\n                        ));\n                    }\n                }\n            }\n        }\n\n        let mut query_params = Vec::new();","sourceCodeStart":986,"sourceCodeEnd":1022,"githubUrl":"https://github.com/DioxusLabs/dioxus/blob/393d190a801ccb441d41923e232289b4f8a5c669/packages/fullstack-macro/src/lib.rs#L986-L1022","documentation":"A wildcard path segment written as `*name` (PathParam::WildCard) only matches 'the rest of the path', so it is only legal as the final segment. RouteParser::new iterates segments and raises this error for any WildCard at index != last (packages/fullstack-macro/src/lib.rs:999-1009).","triggerScenarios":"`#[route(GET, \"/files/*path/meta\")]` — segments after the wildcard; nesting a wildcard mid-path hoping for glob behavior; converting an axum `{*path}/tail` route where axum itself would reject it too.","commonSituations":"Assuming `*` acts like a shell glob that can match one segment in the middle; refactoring `/a/*rest` to `/a/*rest/b` and expecting it to still compile; designing URLs like `/api/*version/users`.","solutions":["Move the wildcard to the end: `/files/{path}/meta` won't work either — instead capture per-segment with `{path}` (single segment) or restructure to `/files/meta/*rest`.","If you need 'one segment anywhere', use a `{name}` capture and parse it yourself.","If you truly need prefix-style matching, register separate routes per prefix and keep each wildcard last."],"exampleFix":"// before\n#[route(GET, \"/api/*version/users\")]\nasync fn users(version: Vec<String>) { ... }\n\n// after\n#[route(GET, \"/api/{version}/users\")]\nasync fn users(version: String) { ... }","handlingStrategy":"validation","validationCode":"fn validate_route(route: &str) -> Result<(), String> {\n    let path = route.split('?').next().unwrap().trim_start_matches('/');\n    let segs: Vec<&str> = path.split('/').collect();\n    for (i, seg) in segs.iter().enumerate() {\n        if seg.starts_with('*') && i != segs.len() - 1 {\n            return Err(format!(\"wildcard must be last segment: {route}\"));\n        }\n    }\n    Ok(())\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Design URLs so catch-alls only ever terminate the path.","For 'one segment anywhere' semantics use {name} captures, not *."],"tags":["dioxus","proc-macro","routes","wildcard","path-params","compile-time"],"backgroundTag":null,"analyzedSha":"393d190a801ccb441d41923e232289b4f8a5c669","analyzedAt":"2026-08-16T11:27:45.815Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}