{"record":{"id":"6b42c7da5e7a3c2e","repo":"DioxusLabs/dioxus","slug":"expected-path-to-start-with","errorCode":null,"errorMessage":"expected path to start with '/'","messagePattern":"expected path to start with '/'","errorType":"validation","errorClass":"syn::Error","httpStatus":null,"severity":"error","filePath":"packages/fullstack-macro/src/lib.rs","lineNumber":986,"sourceCode":"}\n\nstruct RouteParser {\n    path_params: Vec<(Slash, PathParam)>,\n    query_params: Vec<QueryParam>,\n}\n\nimpl RouteParser {\n    fn new(lit: LitStr) -> syn::Result<Self> {\n        let val = lit.value();\n        let span = lit.span();\n        let split_route = val.split('?').collect::<Vec<_>>();\n        if split_route.len() > 2 {\n            return Err(syn::Error::new(span, \"expected at most one '?'\"));\n        }\n\n        let path = split_route[0];\n        if !path.starts_with('/') {\n            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(","sourceCodeStart":968,"sourceCodeEnd":1004,"githubUrl":"https://github.com/DioxusLabs/dioxus/blob/393d190a801ccb441d41923e232289b4f8a5c669/packages/fullstack-macro/src/lib.rs#L968-L1004","documentation":"RouteParser::new requires the path portion of the route literal to start with `/` (packages/fullstack-macro/src/lib.rs:985-988). Without a leading slash the generated axum route would be relative/invalid, so the macro refuses it immediately.","triggerScenarios":"`#[route(GET, \"items/{id}\")]`; `#[get(\"home\")]`; building the string with `format!`-like composition in source and dropping the slash; porting a frontend Dioxus router route (which does not need a leading slash in some contexts) into a fullstack route attribute.","commonSituations":"Confusion between client-side `#[route]` (dioxus-router) and server-side fullstack `#[route]` conventions; typos; trimming slashes during copy-paste.","solutions":["Add the leading slash: `#[route(GET, \"/items/{id}\")]`.","Double-check any route constants shared between client and server — the server macro always requires the slash.","If the intent was a client-side page route, use dioxus-router's route macro instead of the fullstack one."],"exampleFix":"// before\n#[route(GET, \"items/{id}\")]\nasync fn item(id: i32) { ... }\n\n// after\n#[route(GET, \"/items/{id}\")]\nasync fn item(id: i32) { ... }","handlingStrategy":"validation","validationCode":"fn validate_route(route: &str) -> Result<(), String> {\n    let path = route.split('?').next().unwrap();\n    if !path.starts_with('/') {\n        return Err(format!(\"path must start with '/': {route}\"));\n    }\n    Ok(())\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never reuse dioxus-router client route strings verbatim in fullstack route attributes without checking the leading slash.","Keep route strings in consts so a single test can validate them all."],"tags":["dioxus","proc-macro","routes","path-format","compile-time"],"backgroundTag":null,"analyzedSha":"393d190a801ccb441d41923e232289b4f8a5c669","analyzedAt":"2026-08-16T11:27:45.815Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}