Unity-Technologies/UnityCsReference · error · InvalidOperationException

Asset {objectToAdd} has a non-null path. Build profile compo

Error message

Asset {objectToAdd} has a non-null path. Build profile components should be sub-assets.

What it means

Thrown by BuildProfile.AddComponent<T> when the object to add already has a non-empty asset path (AssetDatabase.GetAssetPath returns a path). Build profile components must be sub-assets of the profile asset itself, not independent assets referenced by path. The code path that handles empty assetPath adds the object as a sub-asset and returns; otherwise it throws InvalidOperationException, noting a future API will support reference-style components.

Source

Thrown at Editor/Mono/BuildProfile/BuildProfile.API.cs:127

            }

            // Don't allow duplicates
            var found = GetComponent<T>();
            if (found != null)
            {
                throw new ArgumentException($"The component {typeof(T).Name} already exists in the build profile {name}.");
            }

            var assetPath = AssetDatabase.GetAssetPath(objectToAdd);
            if (string.IsNullOrEmpty(assetPath))
            {
                objectToAdd.hideFlags |= HideFlags.HideInHierarchy;
                AssetDatabase.AddObjectToAsset(objectToAdd, this);
                return;
            }

            // TODO: Future API will support build profile components as reference.
            throw new InvalidOperationException($"Asset {objectToAdd} has a non-null path. Build profile components should be sub-assets.");
        }

        /// <summary>
        /// Removes the first occurence of a component of type T from the build profile.
        /// </summary>
        public void RemoveComponent<T>() where T : UnityEngine.Object
        {
            var found = GetComponent<T>();
            if (found == null)
            {
                Debug.LogWarning($"The component {typeof(T).Name} does not exist in the build profile {name}. ");
                return;
            }

            if (Array.IndexOf(this.requiredComponents, found) > -1)
                throw new ArgumentException($"The component {typeof(T).Name} is required and cannot be removed from the build profile {name}.");

            AssetDatabase.RemoveObjectFromAsset(found);

View on GitHub (pinned to 225b0fbdb5)

Solutions

  1. Pass a fresh, unsaved ScriptableObject instance (one with no asset path) so it can be added as a sub-asset.
  2. If you must use an existing asset, first remove it from its current asset file or create a new instance with ScriptableObject.CreateInstance and copy its data.
  3. Await/track the future API referenced by the TODO for reference-style components.

Example fix

// before
var existing = AssetDatabase.LoadAssetAtPath<MySettings>("Assets/x.asset");
profile.AddComponent(existing); // has a path -> throws

// after
var fresh = ScriptableObject.CreateInstance<MySettings>();
EditorUtility.CopySerialized(existing, fresh);
profile.AddComponent(fresh);
Defensive patterns

Strategy: validation

Validate before calling

if (!string.IsNullOrEmpty(AssetDatabase.GetAssetPath(obj))) { /* has a path; create fresh instead */ }

Type guard

static bool IsUnsaved(UnityEngine.Object o) => string.IsNullOrEmpty(AssetDatabase.GetAssetPath(o));

Prevention

When it happens

Trigger: Passing an object that is already saved as its own asset (e.g. created via AssetDatabase.CreateAsset) to AddComponent. Because GetAssetPath returns the file path, the method refuses and throws.

Common situations: Loading an existing .asset ScriptableObject and trying to attach it to a profile; re-parenting an asset that was authored standalone in the project; copying/moving components between profiles that were saved independently.

Related errors


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