bevyengine/bevy · error

{}

Error message

{}

What it means

build_settings_registry in bevy_settings accumulates errors while building the settings registry (e.g. duplicate resource types, conflicting groups/files) and panics by joining them with newlines if any occurred. It's a fail-fast registration-time panic surfacing multiple settings-definition problems at once.

Solutions

  1. Read the joined panic message — it lists each conflicting entry — and remove the duplicate resource type declarations
  2. Assign each resource type to exactly one settings file/group
  3. Split settings into distinct resources so merged groups don't collide

Example fix

// before
// both files declare
#[derive(Settings)] struct PlayerSettings; // registered twice

// after
// keep PlayerSettings in one file/group only, or rename one to UniquePlayerSettings
Defensive patterns

Strategy: try-catch

Try / catch

let result = std::panic::catch_unwind(|| Settings::build(app));
if let Err(e) = result { eprintln!("Settings registry build failed: {:?}", e); }

Prevention

When it happens

Trigger: Calling Settings::build / build_settings_registry where settings definitions conflict — e.g. the same resource type declared in multiple files or groups, or invalid settings file definitions — producing a non-empty errors vec.

Common situations: Two settings files mapping to the same Rust resource; merging groups that duplicate resource_type entries; test builds combining settings from separate files that overlap.

Understand the failure class

Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.

Related errors


AI-assisted analysis of bevyengine/bevy@a62cce8c05 (2026-09-19). Data as JSON: /api/errors/110de7fd84e858c1. Report an issue: GitHub.

Appendix: source

Thrown at crates/bevy_settings/src/lib.rs:498

                ty.type_info().type_path()
            ));
            continue;
        };

        // If no filename is specified, use "settings"
        let filename = reflect_group.settings_source.unwrap_or("settings");
        let pending_file = file_index
            .files
            .entry(filename)
            .or_insert(SettingsFileManifest {
                last_save,
                resource_types: Vec::new(),
            });
        pending_file.last_save = last_save;
        pending_file.resource_types.push(ty.type_id());
    }
    if !errors.is_empty() {
        panic!("{}", errors.join("\n"));
    }

    file_index
}

/// Loads a single settings file and applies its values to the world's resources.
fn load_settings_file(
    world: &mut World,
    app_name: &str,
    filename: &str,
    manifest: &SettingsFileManifest,
    types: &TypeRegistry,
) {
    // Load the TOML file
    let store = SettingsStore::new(app_name);
    let toml = store.load(filename);
    if toml.is_none() {
        warn!("Filename {filename}.toml not found");

View on GitHub (pinned to a62cce8c05)