{"record":{"id":"e5fa9c3521ccc498","repo":"rwf2/Rocket","slug":"badident","errorCode":"BadIdent","errorMessage":"invalid identifier","messagePattern":"invalid identifier","errorType":"validation","errorClass":"rocket_codegen::param::Error","httpStatus":null,"severity":"error","filePath":"core/codegen/src/attribute/param/parse.rs","lineNumber":63,"sourceCode":"        segment: &str,\n        source_span: Span,\n    ) -> Result<Self, Error<'_>>  {\n        let mut trailing = false;\n\n        // Check if this is a dynamic param. If so, check its well-formedness.\n        let lint = Lint::SegmentChars;\n        if segment.starts_with('<') && segment.ends_with('>') {\n            let mut name = &segment[1..(segment.len() - 1)];\n            if name.ends_with(\"..\") {\n                trailing = true;\n                name = &name[..(name.len() - 2)];\n            }\n\n            let span = subspan(name, segment, source_span);\n            if name.is_empty() {\n                return Err(Error::new(name, source_span, ErrorKind::Empty));\n            } else if !is_valid_ident(name) {\n                return Err(Error::new(name, span, ErrorKind::BadIdent));\n            }\n\n            let dynamic = Dynamic { name: Name::new(name, span), trailing, index: 0 };\n            if dynamic.is_wild() && P::KIND != Kind::Path {\n                return Err(Error::new(name, span, ErrorKind::Ignored));\n            } else if dynamic.is_wild() {\n                return Ok(Parameter::Ignored(dynamic));\n            } else {\n                return Ok(Parameter::Dynamic(dynamic));\n            }\n        } else if segment.is_empty() {\n            return Err(Error::new(segment, source_span, ErrorKind::Empty));\n        } else if segment.starts_with('<') && lint.enabled(source_span) {\n            let candidate = candidate_from_malformed(segment);\n            source_span.warning(\"`segment` starts with `<` but does not end with `>`\")\n                .help(format!(\"perhaps you meant the dynamic parameter `<{}>`?\", candidate))\n                .note(lint.how_to_suppress())\n                .emit_as_item_tokens();","sourceCodeStart":45,"sourceCodeEnd":81,"githubUrl":"https://github.com/rwf2/Rocket/blob/3a54d079aef060a8f732bd04ea54b0581a604087/core/codegen/src/attribute/param/parse.rs#L45-L81","documentation":"Compile-time error from Rocket's codegen: the name inside a dynamic route parameter <name> is not a valid Rust identifier (is_valid_ident failed), so Rocket cannot generate a binding for it. The name must be a valid identifier because it is used to match against a function argument in the generated code. The error span covers just the offending name inside the brackets.","triggerScenarios":"Route parameters containing hyphens, leading digits, spaces, or other non-ident characters: #[get(\"/<user-id>\")], #[get(\"/<0id>\")], #[get(\"/<user id..>\")].","commonSituations":"Mirroring URL naming (kebab-case) into the parameter name instead of the function argument; renaming a path segment for SEO without updating the parameter; typos inserting invisible characters or spaces.","solutions":["Rename the parameter to a valid snake_case Rust identifier: <user_id> instead of <user-id>","Keep the pretty URL only if you don't need the value; otherwise map it in the handler, since the parameter name must equal the function argument name","Check for stray characters (spaces, unicode dashes) if the name looks valid"],"exampleFix":"// before\n#[get(\"/users/<user-id>\")]\nfn user(user_id: &str) { }\n\n// after\n#[get(\"/users/<user_id>\")]\nfn user(user_id: &str) { }","handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use snake_case for route parameter names; keep kebab-case only in static path text","Parameter name must equal the handler argument name","cargo check after renaming path segments"],"tags":["rust","rocket","proc-macro","codegen","compile-time","identifier"],"backgroundTag":"invalid-identifier","analyzedSha":"3a54d079aef060a8f732bd04ea54b0581a604087","analyzedAt":"2026-08-16T22:01:48.395Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}