Unity-Technologies/UnityCsReference · error · Exception

Config object with name '${name}' already exists.

Error message

Config object with name '${name}' already exists.

What it means

Thrown by EditorBuildSettings.AddConfigObject when the native AddConfigObjectInternal returns ConfigObjectResult.FailedEntryExists — a config object with the given name is already stored and overwrite was false. Config objects are arbitrary key→UnityEngine.Object associations persisted in EditorBuildSettings (per-build-target editor config). The native side returns a result enum rather than overwriting silently.

Source

Thrown at Editor/Mono/EditorBuildSettings.bindings.cs:174

        }

        [Obsolete("UseParallelAssetBundleBuilding is obsolete and will be removed.")]
        [NoAutoStaticsCleanup] // deprecated value-type setting; safe to persist across reload
        public static bool UseParallelAssetBundleBuilding { get; set; } = false;

        [NativeMethod("AddConfigObject")]
        static extern ConfigObjectResult AddConfigObjectInternal(string name, Object obj, bool overwrite);
        public static extern bool RemoveConfigObject(string name);
        public static extern string[] GetConfigObjectNames();
        static extern Object GetConfigObject(string name);
        public static void AddConfigObject(string name, Object obj, bool overwrite)
        {
            var result = AddConfigObjectInternal(name, obj, overwrite);
            if (result == ConfigObjectResult.Succeeded)
                return;
            switch (result)
            {
                case ConfigObjectResult.FailedEntryExists: throw new Exception("Config object with name '" + name + "' already exists.");
                case ConfigObjectResult.FailedNonPersistedObj: throw new Exception("Cannot add non-persisted config object with name '" + name + "'.");
                case ConfigObjectResult.FailedNullObj: throw new Exception("Cannot add null config object with name '" + name + "'.");
            }
        }

        public static bool TryGetConfigObject<T>(string name, out T result) where T : Object
        {
            result = GetConfigObject(name) as T;
            return result != null;
        }
    }
}

View on GitHub (pinned to 225b0fbdb5)

Solutions

  1. Pass overwrite:true when you intend to replace an existing entry.
  2. Remove first: if (EditorBuildSettings.GetConfigObjectNames().Contains(name)) EditorBuildSettings.RemoveConfigObject(name);
  3. Use a unique, namespaced key per script/package to avoid collisions.

Example fix

// before
EditorBuildSettings.AddConfigObject("MyConfig", asset, overwrite: false);
// after
EditorBuildSettings.AddConfigObject("com.mycompany.MyConfig", asset, overwrite: true);
Defensive patterns

Strategy: validation

Validate before calling

if (Array.IndexOf(EditorBuildSettings.GetConfigObjectNames(), name) >= 0)
    EditorBuildSettings.RemoveConfigObject(name);
EditorBuildSettings.AddConfigObject(name, obj, overwrite: true);

Try / catch

try { EditorBuildSettings.AddConfigObject(name, obj, overwrite: false); }
catch (Exception ex) when (ex.Message.Contains("already exists"))
{ /* entry present; remove or pass overwrite:true */ }

Prevention

When it happens

Trigger: Calling EditorBuildSettings.AddConfigObject(name, obj, overwrite:false) when GetConfigObjectNames() already contains 'name'. Re-running a setup script without first removing the entry or without overwrite:true.

Common situations: Build pipeline initialization scripts that register config objects and are re-run (iteration, CI without a clean state); two packages/scripts using the same config key.

Related errors


AI-assisted analysis of Unity-Technologies/UnityCsReference@225b0fbdb5 (2026-08-13). Data as JSON: /api/errors/36702f39d75aa0d6. Report an issue: GitHub.