{"record":{"id":"c5f6a70d2e99e36e","repo":"bevyengine/bevy","slug":"failed-to-parse-substate-sources","errorCode":null,"errorMessage":"Failed to parse substate sources","messagePattern":"Failed to parse substate sources","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/bevy_state/macros/src/states.rs","lineNumber":87,"sourceCode":"        .collect::<Result<Vec<_>>>()?;\n\n    if result.len() > 1 {\n        return Err(syn::Error::new(\n            ast.span(),\n            \"Only one source is allowed for SubStates\",\n        ));\n    }\n\n    let Some(result) = result.pop() else {\n        return Err(syn::Error::new(ast.span(), \"SubStates require a source\"));\n    };\n\n    Ok(result)\n}\n\npub fn derive_substates(input: TokenStream) -> TokenStream {\n    let ast = parse_macro_input!(input as DeriveInput);\n    let sources = parse_sources_attr(&ast).expect(\"Failed to parse substate sources\");\n\n    let generics = ast.generics;\n    let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();\n\n    let mut base_trait_path = bevy_state_path();\n    base_trait_path.segments.push(format_ident!(\"state\").into());\n\n    let mut trait_path = base_trait_path.clone();\n    trait_path.segments.push(format_ident!(\"SubStates\").into());\n\n    let mut state_set_trait_path = base_trait_path.clone();\n    state_set_trait_path\n        .segments\n        .push(format_ident!(\"StateSet\").into());\n\n    let mut state_trait_path = base_trait_path.clone();\n    state_trait_path\n        .segments","sourceCodeStart":69,"sourceCodeEnd":105,"githubUrl":"https://github.com/bevyengine/bevy/blob/396ca727080776bd313bb892423b7d94e03b81b4/crates/bevy_state/macros/src/states.rs#L69-L105","documentation":"derive_substates calls parse_sources_attr(&ast).expect(\"Failed to parse substate sources\") (states.rs:85-87). parse_sources_attr returns Err when syn fails parsing inside the attribute — e.g. `#[source(AppState)]` missing the `= value` pair (nested.value()? errors), or the value after `=` is not a valid pattern. The expect turns that syn error into a proc-macro panic, which surfaces as this compile error.","triggerScenarios":"A `#[source(...)]` attribute whose contents are syntactically invalid for the `path = pattern` grammar: missing `=`, missing value, or a value that cannot be parsed as a Pat.","commonSituations":"Hand-writing the attribute for the first time; examples/docs drift across Bevy versions; refactoring state names inside the attribute and leaving fragments behind.","solutions":["Restore the exact form `#[source(AppState = AppState::InGame)]`","Ensure the right side is a valid pattern (a path/variant expression), not arbitrary tokens","Run cargo expand on the type if unsure what the macro received"],"exampleFix":"// before — missing `= value` pair, syn parse fails inside the attribute\n#[derive(SubStates, Debug, Hash, PartialEq, Eq, Clone)]\n#[source(AppState)]\nenum MenuState { MainMenu, Paused }\n\n// after\n#[derive(SubStates, Debug, Hash, PartialEq, Eq, Clone)]\n#[source(AppState = AppState::InGame)]\nenum MenuState { MainMenu, Paused }","handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":["Write the source as `#[source(StateType = StateType::Variant)]` — both sides are required","Keep the value side a plain path/variant pattern; no expressions or generics"],"tags":["bevy","states","proc-macro","derive","compile-error","syn"],"backgroundTag":"derive-macro-attribute-invalid","analyzedSha":"396ca727080776bd313bb892423b7d94e03b81b4","analyzedAt":"2026-08-20T16:12:39.808Z","contentChangedAt":"2026-08-20T16:12:39.808Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}