{"record":{"id":"8f60839210734914","repo":"DioxusLabs/dioxus","slug":"expected-at-most-one","errorCode":null,"errorMessage":"expected at most one '?'","messagePattern":"expected at most one '\\?'","errorType":"validation","errorClass":"syn::Error","httpStatus":null,"severity":"error","filePath":"packages/fullstack-macro/src/lib.rs","lineNumber":981,"sourceCode":"            url_without_queries\n        );\n\n        Some(full_url)\n    }\n}\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();","sourceCodeStart":963,"sourceCodeEnd":999,"githubUrl":"https://github.com/DioxusLabs/dioxus/blob/393d190a801ccb441d41923e232289b4f8a5c669/packages/fullstack-macro/src/lib.rs#L963-L999","documentation":"RouteParser::new splits the route literal on `?` and requires at most two parts (path, query). More than one `?` means the string is malformed — the second `?` would end up inside the query section and produce nonsense, so it is rejected up front (packages/fullstack-macro/src/lib.rs:975-979).","triggerScenarios":"`#[route(GET, \"/search?q=?other\")]`; a query value containing a literal `?` such as `?q=a?b`; accidentally concatenating two route strings that each had their own query, e.g. `\"/list?sort\" + \"&?page\"`.","commonSituations":"Building route strings dynamically at authoring time; copying a URL with an embedded `?` from a browser address bar; misunderstanding that `?` is a structural separator here, not data.","solutions":["Keep exactly one `?` between path and query: `/search?q&other`.","If a query value may contain `?`, it must be percent-encoded by the client (`%3F`) — never place a raw `?` in the route literal.","Delete the stray `?` produced by string concatenation and use `&` between query params."],"exampleFix":"// before\n#[route(GET, \"/search?q=?other\")]\nasync fn search(q: String, other: String) { ... }\n\n// after\n#[route(GET, \"/search?q&other\")]\nasync fn search(q: String, other: String) { ... }","handlingStrategy":"validation","validationCode":"fn validate_route(route: &str) -> Result<(), String> {\n    if route.split('?').count() > 2 {\n        return Err(format!(\"expected at most one '?': {route}\"));\n    }\n    Ok(())\n}\n// Unit-test every route constant/string before committing:\n#[test]\nfn routes_well_formed() { for r in [\"/items/{id}\", \"/search?q\"] { validate_route(r).unwrap(); } }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Treat '?' as structural: exactly one separator, '&' between query keys, never data.","Percent-encode any literal '?' inside values (%3F) on the client side."],"tags":["dioxus","proc-macro","routes","query-string","compile-time"],"backgroundTag":null,"analyzedSha":"393d190a801ccb441d41923e232289b4f8a5c669","analyzedAt":"2026-08-16T11:27:45.815Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}