{"record":{"id":"cd6a5679c80117f6","repo":"DioxusLabs/dioxus","slug":"expected-path-param-to-be-wrapped-in-curly-braces","errorCode":null,"errorMessage":"expected path param to be wrapped in curly braces","messagePattern":"expected path param to be wrapped in curly braces","errorType":"validation","errorClass":"syn::Error","httpStatus":null,"severity":"error","filePath":"packages/fullstack-macro/src/lib.rs","lineNumber":1109,"sourceCode":"        matches!(self, Self::Capture(..) | Self::WildCard(..))\n    }\n\n    fn capture(&self) -> Option<(&Ident, &Type)> {\n        match self {\n            Self::Capture(_, _, ident, ty, _) => Some((ident, ty)),\n            Self::WildCard(_, _, _, ident, ty, _) => Some((ident, ty)),\n            _ => None,\n        }\n    }\n\n    fn new(str: &str, span: Span, ty: Box<Type>) -> syn::Result<Self> {\n        let ok = if str.starts_with('{') {\n            let str = str\n                .strip_prefix('{')\n                .unwrap()\n                .strip_suffix('}')\n                .ok_or_else(|| {\n                    syn::Error::new(span, \"expected path param to be wrapped in curly braces\")\n                })?;\n            Self::Capture(\n                LitStr::new(str, span),\n                Brace(span),\n                Ident::new(str, span),\n                ty,\n                Brace(span),\n            )\n        } else if str.starts_with('*') && str.len() > 1 {\n            let str = str.strip_prefix('*').unwrap();\n            Self::WildCard(\n                LitStr::new(str, span),\n                Brace(span),\n                Star(span),\n                Ident::new(str, span),\n                ty,\n                Brace(span),\n            )","sourceCodeStart":1091,"sourceCodeEnd":1127,"githubUrl":"https://github.com/DioxusLabs/dioxus/blob/393d190a801ccb441d41923e232289b4f8a5c669/packages/fullstack-macro/src/lib.rs#L1091-L1127","documentation":"PathParam::new treats a segment starting with `{` as a capture and requires a matching closing `}`. If the opening brace has no suffix brace, the segment is neither valid capture nor static text, so it is rejected (packages/fullstack-macro/src/lib.rs:1102-1110).","triggerScenarios":"`#[route(GET, \"/blog/{id\")]`; `/user/{id}}` style typos (unbalanced braces); segments like `/{a{b}` where inner braces confuse the pairing; JSON-template leftovers such as `/{id}` being edited down to `/{id`.","commonSituations":"Hand-editing route strings and dropping a brace; generating routes from templating systems that strip characters; pasting from docs where markdown mangled the braces.","solutions":["Balance the braces: `/blog/{id}`.","If you need a literal `{` or `}` in a static segment, percent-encode or choose different static text — braces are reserved for captures.","Re-read each capture as `{ident}` exactly one identifier, nothing else inside."],"exampleFix":"// before\n#[route(GET, \"/blog/{id\")]\nasync fn blog(id: i32) { ... }\n\n// after\n#[route(GET, \"/blog/{id}\")]\nasync fn blog(id: i32) { ... }","handlingStrategy":"validation","validationCode":"fn validate_route(route: &str) -> Result<(), String> {\n    let path = route.split('?').next().unwrap();\n    for seg in path.trim_start_matches('/').split('/') {\n        if seg.starts_with('{') && !seg.ends_with('}') {\n            return Err(format!(\"unbalanced '{{' in segment {seg:?} of {route}\"));\n        }\n    }\n    Ok(())\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never place braces in static segments; braces exclusively wrap a single identifier.","Run cargo fmt/check immediately after hand-editing route strings."],"tags":["dioxus","proc-macro","routes","path-params","syntax","compile-time"],"backgroundTag":null,"analyzedSha":"393d190a801ccb441d41923e232289b4f8a5c669","analyzedAt":"2026-08-16T11:27:45.815Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}