bevyengine/bevy · error
Failed to parse substate sources
Error message
Failed to parse substate sources
What it means
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.
Source
Thrown at crates/bevy_state/macros/src/states.rs:87
.collect::<Result<Vec<_>>>()?;
if result.len() > 1 {
return Err(syn::Error::new(
ast.span(),
"Only one source is allowed for SubStates",
));
}
let Some(result) = result.pop() else {
return Err(syn::Error::new(ast.span(), "SubStates require a source"));
};
Ok(result)
}
pub fn derive_substates(input: TokenStream) -> TokenStream {
let ast = parse_macro_input!(input as DeriveInput);
let sources = parse_sources_attr(&ast).expect("Failed to parse substate sources");
let generics = ast.generics;
let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
let mut base_trait_path = bevy_state_path();
base_trait_path.segments.push(format_ident!("state").into());
let mut trait_path = base_trait_path.clone();
trait_path.segments.push(format_ident!("SubStates").into());
let mut state_set_trait_path = base_trait_path.clone();
state_set_trait_path
.segments
.push(format_ident!("StateSet").into());
let mut state_trait_path = base_trait_path.clone();
state_trait_path
.segmentsView on GitHub (pinned to 396ca72708)
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
Example fix
// before — missing `= value` pair, syn parse fails inside the attribute
#[derive(SubStates, Debug, Hash, PartialEq, Eq, Clone)]
#[source(AppState)]
enum MenuState { MainMenu, Paused }
// after
#[derive(SubStates, Debug, Hash, PartialEq, Eq, Clone)]
#[source(AppState = AppState::InGame)]
enum MenuState { MainMenu, Paused } Defensive patterns
Strategy: validation
Prevention
- 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
When it happens
Trigger: 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.
Common situations: Hand-writing the attribute for the first time; examples/docs drift across Bevy versions; refactoring state names inside the attribute and leaving fragments behind.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Couldn't parse SubStates source
- Only one source is allowed for SubStates
- SubStates require a source
- Currently, caching is only supported for scene assets. Pleas
- Cannot use scene assets without caching, please add the ':'
AI-assisted analysis of bevyengine/bevy@396ca72708 (2026-08-20).
Data as JSON: /api/errors/c5f6a70d2e99e36e.
Report an issue: GitHub.