bevyengine/bevy · error
bevy_ecs should be found in manifest
Error message
bevy_ecs should be found in manifest
What it means
This expect() panic happens at COMPILE TIME inside the #[derive(ExtractComponent)] macro from bevy_extract. The macro resolves the path to bevy_ecs by scanning the crate manifest (BevyManifest); if 'bevy_ecs' cannot be found as a dependency in the invoking crate's Cargo.toml, maybe_get_path returns None and the derive aborts with 'bevy_ecs should be found in manifest'. It is a build-script/proc-macro environment problem, not a runtime error.
Source
Thrown at crates/bevy_extract/macros/src/extract_component.rs:12
use bevy_macro_utils::fq_std::{FQClone, FQOption};
use proc_macro::TokenStream;
use quote::quote;
use syn::{parse_macro_input, parse_quote, punctuated::Punctuated, DeriveInput, Path};
pub fn derive_extract_component(input: TokenStream) -> TokenStream {
let mut ast = parse_macro_input!(input as DeriveInput);
let bevy_extract_path: Path = crate::bevy_extract_path();
let bevy_ecs_path: Path = bevy_macro_utils::BevyManifest::shared(|manifest| {
manifest
.maybe_get_path("bevy_ecs")
.expect("bevy_ecs should be found in manifest")
});
ast.generics
.make_where_clause()
.predicates
.push(parse_quote! { Self: #FQClone });
let struct_name = &ast.ident;
let (impl_generics, type_generics, where_clause) = &ast.generics.split_for_impl();
let Some(attr) = ast.attrs.iter().find(|a| a.path().is_ident("extract_app")) else {
return syn::Error::new_spanned(
&ast.ident,
"ExtractComponent requires #[extract_app(MyAppLabelA, MyAppLabelB)] to specify the target sub-app(s)",
)
.to_compile_error()
.into();
};View on GitHub (pinned to 396ca72708)
Solutions
- Add bevy_ecs to the invoking crate's Cargo.toml: bevy_ecs = "<matching version>" (or via the bevy umbrella crate at the same version).
- Keep dependency versions in lockstep with bevy_extract/bevy_render to avoid mixed-version manifest lookups.
- If you don't need ECS types in that derive, check whether a re-export path (bevy::ecs) is available and depend on the umbrella bevy crate instead.
- Verify the derive is actually the one you intend (bevy_extract's) and that no custom BevyManifest path env overrides break resolution.
Example fix
# before (Cargo.toml of the deriving crate) [dependencies] bevy_extract = "0.19" # derive fails: bevy_ecs should be found in manifest # after [dependencies] bevy_ecs = "0.19" bevy_extract = "0.19"
Defensive patterns
Strategy: validation
Validate before calling
# In Cargo.toml of the crate using #[derive(ExtractComponent)]: [dependencies] bevy_ecs = "0.19" # must match the bevy_extract/bevy version in use bevy_extract = "0.19"
Prevention
- Every crate that derives Bevy macros must list the referenced Bevy subcrates as direct dependencies.
- Keep all bevy_* dependency versions identical across the workspace (cargo tree -d to check).
- Treat proc-macro 'should be found in manifest' panics as missing-dependency signals, not source bugs.
When it happens
Trigger: Using #[derive(ExtractComponent)] in a crate whose Cargo.toml does not list bevy_ecs as a dependency; depending on bevy_extract (or bevy_render re-exports) without also pulling bevy_ecs; workspace setups where the dependency is renamed or only present as a transitive dep.
Common situations: Splitting a Bevy project into workspace crates and forgetting bevy_ecs in the crate that derives ExtractComponent; using the new bevy_extract crate directly in external code; renaming dependencies in Cargo.toml so manifest path resolution fails.
Related errors
- Unable to read cargo manifest: {}
- Union types are not supported yet.
- Expected a Template type path
- Can only derive VariantDefaults for enums
- Failed to parse cargo manifest: {}
AI-assisted analysis of bevyengine/bevy@396ca72708 (2026-08-20).
Data as JSON: /api/errors/a2fdf4f20cd39634.
Report an issue: GitHub.