---
title: "Pitfalls: DOTS, SubScenes & Burst"
slug: /workflows/pitfalls-dots/
markdown: /workflows/pitfalls-dots.md
section: pitfalls
tier: 2
summary: "Baker isolation, structural changes, Burst cache."
sources: ['pitfalls/dots.md']
canonical: https://unityworkflowlibrary.dev/workflows/pitfalls-dots/
read_first: /read-first.md
---

> Read first, on every prompt: [non-destructive rules](/read-first.md).

# Pitfalls: DOTS, SubScenes & Burst

> Baker isolation, structural changes, Burst cache.

Generalized pitfalls from shipped and active projects. Record your own project's traps the same way: [Keeping a project pitfall file](/workflows/pitfall-file/). All entries LOCKED evidence. Status: locked (empirical, seen in shipped/active projects).

- **BAKERS-DO-NOT-SEE-THE-MAIN-SCENE — bakers cannot reliably find main-scene MonoBehaviours; they run in an isolated SubScene context.** Check: bakers read only their authoring component and referenced assets. See also SUBSCENE-RUNTIME-BOUNDARY (the ecs core page). Status: locked (empirical, seen in shipped/active projects).
- **DO-NOT-NAME-A-NESTED-CLASS-BAKER — a nested class called `Baker` shadows `Baker<T>` and fails to compile (CS0308).** Check: name bakers `<Authoring>Baker`. Status: locked (empirical, seen in shipped/active projects).
- **MONOBEHAVIOUR-FILE-NAME-MATCHES-CLASS — a MonoBehaviour/ScriptableObject whose file name differs from the class cannot be added ("needs to derive from MonoBehaviour").** Check: one Unity object type per file, file named after it. Status: locked (empirical, seen in shipped/active projects).
- **NO-STRUCTURAL-CHANGES-INSIDE-QUERY-FOREACH — calling structural `EntityManager` APIs inside an idiomatic `SystemAPI.Query` foreach throws.** Check: record into an `EntityCommandBuffer` and play back after the loop. Status: locked (empirical, seen in shipped/active projects).
- **DESTROY-BY-QUERY-AND-LINKED-GROUPS — `DestroyEntity(EntityQuery)` fails when a `LinkedEntityGroup` points at entities outside the query.** Check: destroy roots through an ECB (which follows linked groups) or include children. Status: locked (empirical, seen in shipped/active projects).
- **BAKE-PREFABS-FROM-ASSETS — a baker's `GetEntity(prefab)` must receive a project Prefab asset, not a scene instance.** Check: authoring fields for spawnable prefabs reference assets only. Status: locked (empirical, seen in shipped/active projects).
- **SPAWNER-AUTHORING-OFF-THE-PREFAB — a baker that creates additional entities must not sit on the prefab it spawns.** Check: spawners live on separate authoring objects. Status: locked (empirical, seen in shipped/active projects).

> **Why this rule exists** (SPAWNER-AUTHORING-OFF-THE-PREFAB): The spawner baked into every spawned copy, recursively spawning.
> *Source: Pitfall log of a shipped or active Unity project, generalized.*

- **KEEP-SCENE-TAGS-ON-CLONES — do not strip `SceneTag`/`SceneSection` from runtime clones to "detach" them.** Why: it changes archetype and breaks section unload bookkeeping. Status: locked (empirical, seen in shipped/active projects).
- **SKINNED-PREFABS-BECOME-COMPANIONS — SkinnedMeshRenderer+Animator prefabs bake as companion GameObjects unless a skinning package converts them.** Check: budget companions as GameObjects; use an ECS animation solution for crowds. Status: locked (empirical, seen in shipped/active projects).
- **CROSS-BOUNDARY-REFERENCES-USE-BAKED-MARKERS — references across the main-scene/SubScene boundary break at play; query a baked marker component instead.** Status: locked (empirical, seen in shipped/active projects).
- **DEFAULT-WORLD-NOT-WORLD-ZERO — MonoBehaviour-side ECS access targets `World.DefaultGameObjectInjectionWorld` (or the named client world), never `World.All[0]`.** Why: with netcode, several worlds exist and order varies. Status: locked (empirical, seen in shipped/active projects).
- **INITIALIZEONLOAD-SUBSCRIPTIONS-STACK — `[InitializeOnLoadMethod]` runs every domain reload; subscribing to static events there without unsubscribing stacks handlers.** Check: unsubscribe before subscribing. Status: locked (empirical, seen in shipped/active projects).
- **ONVALIDATE-AUTOFILL-BEFORE-GUARDS — OnValidate auto-fill must run before any debounce/early-return guard.** Why: non-serialized guard flags reset unpredictably, skipping the fill. Status: locked (empirical, seen in shipped/active projects).
- **BURST-JOB-FIELD-CHANGES-CAN-NO-OP — adding a field to a Burst job struct can silently do nothing until the Burst cache is invalidated.** Check: after job layout changes, force a Burst recompile and assert the new output. See also EDITOR-BURST-CAN-SKIP-A-RECOMPILE. Status: locked (empirical, seen in shipped/active projects).
- **COMPLETE-JOBS-BEFORE-OUT-OF-BAND-RENDER — code calling `Camera.Render` during Play must complete tracked jobs first.** Status: locked (empirical, seen in shipped/active projects).

> **Why this rule exists** (COMPLETE-JOBS-BEFORE-OUT-OF-BAND-RENDER): Out-of-band renders raced ECS jobs writing render data.
> *Source: Pitfall log of a shipped or active Unity project, generalized.*

- **ENTITY-PREFABS-ONLY-BAKE-IN-SUBSCENES — a main-scene "catalog" baker is dormant.** Check: catalogs of entity prefabs live in a SubScene. Status: locked (empirical, seen in shipped/active projects).
- **SUBSCENE-IMPORT-MISSES-NESTED-ASSET-EDITS — the SubScene importer does not dependency-track a material/mesh swapped inside a baked prefab, nor a referenced ScriptableObject's own fields read in `Bake`.** Check: declare dependencies (`DependsOn`) for every asset whose fields a baker reads; reimport after nested edits. Status: locked (empirical, seen in shipped/active projects).
- **HOLD-NO-BUFFER-ACROSS-STRUCTURAL-CHANGE — a `DynamicBuffer` handle is invalidated by any later add/remove on the entity.** Check: do all structural adds first, then `GetBuffer` and fill. Status: locked (empirical, seen in shipped/active projects).

> **Why this rule exists** (HOLD-NO-BUFFER-ACROSS-STRUCTURAL-CHANGE): `AddBuffer` then another `AddComponent`, then writing the first buffer threw ObjectDisposedException.
> *Source: Pitfall log of a shipped or active Unity project, generalized.*

- **NO-ENGINE-NAMESPACE-SEGMENTS — a project namespace segment named after an engine type (`.Debug`, `.Editor`) hijacks bare references.** Check: avoid engine type names as namespace segments, or fully qualify (`UnityEngine.Debug`). Status: locked (empirical, seen in shipped/active projects).

> **Why this rule exists** (NO-ENGINE-NAMESPACE-SEGMENTS): Inside a `...AI.Debug` namespace every `Debug.Log` resolved to the project namespace; `namespace X.Editor` stole `typeof(Editor)`.
> *Source: Pitfall log of a shipped or active Unity project, generalized.*

- **DONTSAVE-OBJECTS-OUTLIVE-PLAY — runtime-created objects flagged `HideFlags.DontSave` are not destroyed at Play exit.** Check: destroy them explicitly on exit. See also DONTSAVE-IS-INVISIBLE-TO-FINDOBJECTSBYTYPE. Status: locked (empirical, seen in shipped/active projects).
