bevyengine/bevy · error · SystemTypeSetAmbiguityError

Tried to order against `{0:?}` in a schedule that has more t

Error message

Tried to order against `{0:?}` in a schedule that has more than one `{0:?}` instance. `{0:?}` is a `SystemTypeSet` and cannot be used for ordering if ambiguous. Use a different set without this restriction.

What it means

Ordering against a system by type (.before(fn_name) etc., where the function becomes a SystemTypeSet matched by type, not instance) is only permitted when the schedule holds at most one system of that type. SystemSets::check_type_set_ambiguity found more than one instance, so the constraint cannot be resolved to a single target. Returned as part of ScheduleBuildError during schedule initialization.

Source

Thrown at crates/bevy_ecs/src/schedule/node.rs:909

}

impl Index<SystemSetKey> for SystemSets {
    type Output = dyn SystemSet;

    #[track_caller]
    fn index(&self, key: SystemSetKey) -> &Self::Output {
        self.get(key).unwrap_or_else(|| {
            panic!(
                "System set with key {:?} does not exist in the schedule",
                key
            )
        })
    }
}

/// Error returned when calling [`SystemSets::check_type_set_ambiguity`].
#[derive(Error, Debug)]
#[error("Tried to order against `{0:?}` in a schedule that has more than one `{0:?}` instance. `{0:?}` is a `SystemTypeSet` and cannot be used for ordering if ambiguous. Use a different set without this restriction.")]
pub struct SystemTypeSetAmbiguityError(pub SystemSetKey);

#[cfg(test)]
mod tests {
    use alloc::{boxed::Box, vec};

    use crate::{
        prelude::SystemSet,
        schedule::{SystemSets, Systems},
        system::IntoSystem,
        world::World,
    };

    #[derive(SystemSet, Clone, Copy, PartialEq, Eq, Debug, Hash)]
    pub struct TestSet;

    #[test]
    fn systems() {

View on GitHub (pinned to 396ca72708)

Solutions

  1. Order against a named SystemSet instead: put the target system(s) in MySet and use .before(MySet)/.after(MySet).
  2. Deduplicate the registration so the function exists once in that schedule.
  3. If multiple instances are intentional, give each a distinct set or wrapper and order against those.

Example fix

// before
app.add_systems(Update, (spawn_wave, spawn_wave.run_if(in_boss)));
app.add_systems(Update, hud.before(spawn_wave)); // which spawn_wave?

// after
app.add_systems(Update, (spawn_wave, spawn_wave.run_if(in_boss)).in_set(SpawnSet));
app.add_systems(Update, hud.before(SpawnSet));
Defensive patterns

Strategy: try-catch

Validate before calling

// After all systems are registered, assert the type is unique before first run
let count = schedule
    .systems()?
    .filter(|(_, s)| s.name().ends_with("spawn_wave"))
    .count();
assert!(count <= 1, "system type used for ordering is duplicated");

Try / catch

match schedule.initialize(&mut world) {
    Ok(()) => {}
    Err(e) if mentions_type_set_ambiguity(&e) => {
        // switch the constraint to a named SystemSet and rebuild
    }
    Err(e) => return Err(e.into()),
}

Prevention

When it happens

Trigger: Calling .before(f)/.after(f) when the function f was added more than once to the same schedule (duplicate add_systems registration, added by a plugin and again manually, or registered by a generic helper twice); the ambiguity is detected while the schedule builds.

Common situations: A plugin registers a system and user code adds it again; parameterized registration helpers that add the same function under multiple conditions; refactoring one system into several instances while old type-based ordering constraints remain.

Related errors


AI-assisted analysis of bevyengine/bevy@396ca72708 (2026-08-20). Data as JSON: /api/errors/297bb6ff60aae264. Report an issue: GitHub.