bevyengine/bevy · critical

System set with key {:?} does not exist in the schedule

Error message

System set with key {:?} does not exist in the schedule

What it means

Panics when the SystemSets container is indexed with a SystemSetKey that is not live in the schedule: the set was removed, the key came from a different schedule, or it was otherwise stale. It comes from the Index<SystemSetKey> impl used by sets[key].

Source

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

                let before = dependency.edges_directed(NodeId::Set(key), Incoming);
                let after = dependency.edges_directed(NodeId::Set(key), Outgoing);
                let relations = before.count() + after.count() + ambiguous_with.count();
                if instances > 1 && relations > 0 {
                    return Err(SystemTypeSetAmbiguityError(key));
                }
            }
        }
        Ok(())
    }
}

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,

View on GitHub (pinned to 396ca72708)

Solutions

  1. Use sets.get(key) and handle None instead of indexing.
  2. Re-query set keys from the owning schedule after any configuration change.
  3. Identify sets by InternedSystemSet/name rather than key for anything persisted across frames.

Example fix

// before
let set = sets[key]; // panics if the key is stale

// after
let Some(set) = sets.get(key) else {
    return; // refresh the key from the schedule before use
};
Defensive patterns

Strategy: validation

Validate before calling

if let Some(set) = sets.get(key) {
    // use the set
} else {
    // stale key: re-query from the owning schedule
}

Type guard

fn set_key_is_live(sets: &SystemSets, key: SystemSetKey) -> bool {
    sets.get(key).is_some()
}

Prevention

When it happens

Trigger: Indexing sets by a key captured before the set was removed; using keys from another schedule's SystemSets map; editor/tooling code caching SystemSetKeys across schedule rebuilds.

Common situations: Debug UIs listing sets by cached keys while configuration changes; dynamic set removal (configure_sets changed between frames); refactors that move sets between schedules.

Related errors


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