Quick answer: One of the two transforms in your SetParent call (or the parent you passed to Instantiate) is the prefab asset, not an object in the scene. Use the instance that Instantiate returns, and check that Inspector fields for parents reference scene objects. Editor scripts should edit prefabs through PrefabUtility.LoadPrefabContents.

This error has the same root cause as most prefab bugs in Unity: a variable you believe holds the spawned copy actually holds the prefab it was spawned from. Unity refuses to restructure the asset at runtime, so you get an error instead of a corrupted prefab.

The exact error

Setting the parent of a transform which resides in a Prefab Asset is disabled to prevent data corruption (GameObject: 'Enemy').

The name in parentheses is the object Unity refused to move.

Cause 1: parenting the prefab instead of the instance

// Wrong: the prefab asset is reparented
Instantiate(enemyPrefab);
enemyPrefab.transform.SetParent(enemiesRoot);

// Right
GameObject enemy = Instantiate(enemyPrefab);
enemy.transform.SetParent(enemiesRoot, false);

// Better: parent in the same call
GameObject enemy = Instantiate(enemyPrefab, enemiesRoot);

Cause 2: the parent field references a prefab

If the object being moved is a fresh instance, the parent may be the asset. A common setup: a UI item prefab is spawned into a “content” transform, and the content field on a prefabbed script was assigned to something inside another prefab asset rather than the instance in the scene. Select the component in the Hierarchy and click the parent field: if it pings an object in the Project window, it is an asset. Reassign it to the scene object, or find it at runtime after spawning.

This often appears after turning a scene object into a prefab: references between objects in the same prefab stay valid, but references from the prefab to scene objects cannot be stored in the asset.

Cause 3: editor scripts

Tools that restructure prefabs must work on loaded prefab contents, not on the asset object from AssetDatabase.LoadAssetAtPath:

GameObject root = PrefabUtility.LoadPrefabContents(path);
Transform socket = root.transform.Find("WeaponSocket");
GameObject sword = (GameObject)PrefabUtility.InstantiatePrefab(swordPrefab);
sword.transform.SetParent(socket, false);
PrefabUtility.SaveAsPrefabAsset(root, path);
PrefabUtility.UnloadPrefabContents(root);

Quick runtime check

static bool IsAsset(Component c) => !c.gameObject.scene.IsValid();

if (IsAsset(parent)) Debug.LogError($"Parent {parent.name} is a prefab asset, not a scene object", parent);

Objects in the Project window have no valid scene; anything in the Hierarchy does.

Prefab reference bugs in builds

In builds these mistakes usually surface as objects spawning at the origin, UI items appearing nowhere, or NullReferenceExceptions further along. Bugnet's Unity SDK hooks Unity's log stream, so exceptions and errors in a player's build are filed automatically with the last log lines, a screenshot, the device, OS and build version, and identical ones stack into a single issue with a count.

Frequently asked questions

What causes “Setting the parent of a transform which resides in a Prefab Asset is disabled”?

SetParent was called on a prefab asset, or with a prefab asset as the parent, instead of on scene instances. Use the object returned by Instantiate and scene references for parents.

How do I instantiate a prefab under a parent in Unity?

Pass the parent to Instantiate, for example Instantiate(prefab, parentTransform), or call SetParent on the returned instance.

How do I change a prefab’s hierarchy from an editor script?

Use PrefabUtility.LoadPrefabContents, modify the loaded objects, save with SaveAsPrefabAsset and call UnloadPrefabContents.

If the Inspector field pings the Project window, it is an asset, and you cannot parent things to it at runtime.