# Ifc Errors Spatial Structure

> Use when IFC elements do not appear in a viewer's model tree, are missing from quantity take-off or facility-management exports, or a buildingSMART validation report flags spatial-structure problems : orphan elements with no spatial container, one element contained in two places at once, an element placed at the wrong spatial level, a deprecated proxy used as a placeholder, or a missing or broken spatial tree. Prevents shipping orphan elements with no IfcRelContainedInSpatialStructure link, mislabelling double containment as a WR31 violation, attaching physical elements with IfcRelAggregates instead of IfcRelContainedInSpatialStructure, using IfcBuildingElementProxy as a void or clearance placeholder in IFC4.3, and building a spatial tree that never reaches IfcProject. Covers orphan-element detection, the IfcElement.ContainedInStructure SET [0:1] inverse, WR31 and WR41, the IfcProject NoDecomposition rule, the IfcSingleProjectInstance global rule, IfcRelReferencedInSpatialStructure for multi-storey elements,

- Skill: `impertio-studio/ifc-errors-spatial-structure` (Agent Skill, multi-file: 4 files)
- Install (CLI): `npx skillmds@latest add impertio-studio/ifc-errors-spatial-structure`
- Raw SKILL.md: https://api.skillmd.com/api/skills/impertio-studio/ifc-errors-spatial-structure/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: AI & ML
- License: MIT
- Author: Impertio-Studio (https://skillmd.com/u/impertio-studio)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/impertio-studio/ifc-errors-spatial-structure

---


# IFC Spatial Structure Errors

Diagnose and fix the errors that break the spatial structure of an IFC file : an
element with no spatial container (an orphan), an element contained twice, an
element placed at the wrong level, a deprecated proxy abused as a placeholder, and
a spatial tree that is missing levels or never reaches `IfcProject`. These errors
leave a file that may still pass EXPRESS schema checks, yet elements vanish from
viewers, quantity take-off, and facility-management exports.

For the spatial-structure MODEL (how the tree is built correctly) see
`ifc-core-spatial-structure` and `ifc-impl-spatial-decomposition`. For abstract
`WHERE`-rule and global-`RULE` errors in general see `ifc-errors-schema-validation`.
For dangling `#id` references see `ifc-errors-broken-references`.

## Quick Reference

### The mandatory spatial skeleton

Every physical element MUST be locatable through one acyclic tree rooted at
`IfcProject`. The tree levels differ by version:

| Level | IFC2x3 | IFC4 | IFC4.3 |
|-------|--------|------|--------|
| Context root | `IfcProject` | `IfcProject` | `IfcProject` |
| Site | `IfcSite` | `IfcSite` | `IfcSite` |
| Facility | `IfcBuilding` | `IfcBuilding` | `IfcFacility` (`IfcBuilding`, `IfcBridge`, `IfcRoad`, `IfcRailway`, `IfcMarineFacility`) |
| Sub-level | `IfcBuildingStorey` | `IfcBuildingStorey` | `IfcFacilityPart` (`IfcBuildingStorey`) |
| Space | `IfcSpace` | `IfcSpace` | `IfcSpace` |

`IfcProject` is NOT a spatial element. It is an `IfcContext` subtype. The tree
attaches BENEATH it via `IfcRelAggregates`.

### The three structuring relationships

| Relationship | Connects | Direction | Use for |
|--------------|----------|-----------|---------|
| `IfcRelAggregates` | spatial level to spatial level, project to site, whole to parts | `RelatingObject` (whole) to `RelatedObjects` SET | Building the tree itself : `IfcProject` to `IfcSite` to `IfcBuilding`/`IfcFacility` to storey to `IfcSpace` |
| `IfcRelContainedInSpatialStructure` | a spatial level to physical elements | `RelatingStructure` (one level) to `RelatedElements` SET OF `IfcProduct` | Placing a wall, beam, door into exactly ONE spatial level |
| `IfcRelReferencedInSpatialStructure` | a spatial level to elements (IFC4, IFC4.3 only) | `RelatingStructure` to `RelatedElements` SET | A SECONDARY, non-hierarchical reference for an element spanning levels |

### Core rules

- ALWAYS attach a physical element to its spatial level with
  `IfcRelContainedInSpatialStructure`. NEVER use `IfcRelAggregates` for that :
  `IfcRelAggregates` builds the tree, it does not place elements in it.
- ALWAYS give every physical `IfcElement` occurrence exactly ONE
  `IfcRelContainedInSpatialStructure` link. Zero links is an orphan ; two links
  violate the `IfcElement.ContainedInStructure` inverse, declared `SET [0:1]`.
- Double containment is NOT a WR31 violation. WR31 forbids putting a SPATIAL
  STRUCTURE element into `RelatedElements`. ALWAYS name the correct rule.
- ALWAYS aggregate every `IfcSpatialStructureElement` up to `IfcProject` or
  another spatial element (WR41). A site with no path to `IfcProject` breaks the
  tree.
- NEVER leave `IfcProject.Decomposes` populated : the `NoDecomposition` `WHERE`
  rule forbids anything aggregating the project.
- IFC4.3 : NEVER use `IfcBuildingElementProxy` as a void or clearance placeholder.
  ALWAYS use `IfcVirtualElement` instead.

## Decision Trees

### Which spatial-structure error is this

```
Symptom ?
├─ element absent from viewer tree / quantity take-off / FM export
│   └─ count its IfcRelContainedInSpatialStructure links
│       ├─ zero links  -> ORPHAN element. Pattern 1.
│       └─ one link    -> not orphaned ; check the level. Pattern 3.
├─ validation flags IfcElement.ContainedInStructure cardinality
│   -> DOUBLE containment (two links). Pattern 2.
├─ validation flags WR31 on IfcRelContainedInSpatialStructure
│   -> a spatial element is wrongly listed in RelatedElements. Pattern 4.
├─ element is in the tree but under the wrong level (door under IfcSite)
│   -> WRONG containment level. Pattern 3.
├─ a proxy is used as a void / clearance / virtual placeholder
│   -> PROXY-as-placeholder misuse. Pattern 5.
└─ no IfcSite, WR41 fails, NoDecomposition fails, or multiple IfcProject
    -> MISSING or BROKEN spatial tree. Pattern 6.
```

### Which spatial level should contain this element

```
What is the element ?
├─ a physical building element (wall, beam, slab, column, pipe)
│   -> contain in the storey it physically belongs to (IfcBuildingStorey).
├─ furniture, sanitary, a sensor, equipment inside a room
│   -> contain in the IfcSpace if the room is modelled, else the storey.
├─ a site element (fence, terrain feature, external pavement)
│   -> contain in IfcSite.
├─ an element spanning two storeys (a stair, a tall facade panel)
│   -> contain in ONE storey ; reference the other storey with
│      IfcRelReferencedInSpatialStructure (IFC4, IFC4.3 only).
└─ a spatial level itself (IfcSpace, IfcBuildingStorey)
    -> NEVER use IfcRelContainedInSpatialStructure. Aggregate it with
       IfcRelAggregates. Putting it in RelatedElements breaks WR31.
```

### Proxy or virtual element : placeholder decision

```
Need a non-physical placeholder (provision for void, clearance, imaginary boundary) ?
├─ file schema is IFC4.3
│   -> use IfcVirtualElement. NEVER IfcBuildingElementProxy : the proxy is
│      deprecated for this use in IFC4.3.0.0.
├─ file schema is IFC2x3 or IFC4
│   -> IfcVirtualElement is preferred for imaginary space boundaries.
│      IfcBuildingElementProxy with PredefinedType PROVISIONFORVOID is the
│      legacy provision-for-void pattern still accepted in these versions.
└─ the object is genuinely a physical, unclassifiable construction element
    -> IfcBuildingElementProxy is correct (any version). It is NOT a misuse here.
```

## Patterns

### Pattern 1 : detect and fix an orphan element

An orphan is a physical `IfcElement` occurrence whose `ContainedInStructure`
inverse resolves to zero `IfcRelContainedInSpatialStructure` instances. The
`SET [0:1]` inverse cardinality ALLOWS zero, so the file can pass EXPRESS schema
validation, yet the element is unreachable by spatial traversal : viewers omit it
from the model tree and quantity take-off skips it.

Detect : for each physical element, check whether any
`IfcRelContainedInSpatialStructure` lists it in `RelatedElements`.

Fix : add ONE `IfcRelContainedInSpatialStructure` whose `RelatingStructure` is the
correct spatial level (see the level decision tree) and whose `RelatedElements`
includes the orphan. NEVER attach it with `IfcRelAggregates`. The buildingSMART
normative `SPS` rule family flags missing containment ; ALWAYS re-validate after
the fix.

### Pattern 2 : fix double containment

Double containment is one element listed in `RelatedElements` of TWO different
`IfcRelContainedInSpatialStructure` instances. It violates the inverse attribute
`IfcElement.ContainedInStructure`, declared `SET [0:1] OF
IfcRelContainedInSpatialStructure FOR RelatedElements`. The compliance check
reports an inverse-cardinality error.

Fix : decide the ONE spatial level that owns the element and keep that single
`IfcRelContainedInSpatialStructure` link. Remove the element from the
`RelatedElements` of every other containment relationship. If the element
genuinely relates to a second level (a stair across two storeys), express that
second link with `IfcRelReferencedInSpatialStructure` (IFC4, IFC4.3). NEVER keep
two `...ContainedInSpatialStructure` links to satisfy both levels.

### Pattern 3 : fix a wrong containment level

The element has exactly one containment link, so it is not an orphan, but the
`RelatingStructure` is the wrong level : a door contained directly in `IfcSite`,
a wall contained in `IfcProject` (impossible : `IfcProject` is not spatial), or
room furniture contained in the storey when the `IfcSpace` exists.

This is schema-valid but semantically wrong : downstream consumers group by
spatial level, so the element lands in the wrong room schedule or floor plan.

Fix : edit the single `IfcRelContainedInSpatialStructure` so `RelatingStructure`
points at the correct level per the level decision tree. ALWAYS contain a
physical building element in its `IfcBuildingStorey` ; contain room-scoped
contents in the `IfcSpace` when that space is modelled.

### Pattern 4 : fix a WR31 violation

WR31 on `IfcRelContainedInSpatialStructure` states verbatim : "The relationship
object shall not be used to include other spatial structure elements into a
spatial structure element. The hierarchy of the spatial structure is defined
using `IfcRelAggregates`." The rule is identical in IFC2x3, IFC4, and IFC4.3.

The violation : a spatial structure element (an `IfcSpace`, `IfcBuildingStorey`,
`IfcBuilding`, `IfcSite`, ...) appears in the `RelatedElements` SET of an
`IfcRelContainedInSpatialStructure`. The author used containment where
aggregation was required.

Fix : remove the spatial element from `RelatedElements` and connect it to its
parent level with `IfcRelAggregates` instead (`RelatingObject` = parent level,
`RelatedObjects` includes the spatial element). WR31 is NOT about double
containment ; NEVER report it as such.

### Pattern 5 : replace a proxy-as-placeholder with IfcVirtualElement

`IfcBuildingElementProxy` is the escape hatch for genuinely unclassifiable
PHYSICAL construction elements. It is misused when it stands in for a
non-physical placeholder : a provision for void, a clearance zone, an imaginary
space boundary.

IFC4.3 made this explicit. The IFC4.3.0.0 change note states virtual elements
"can now be used for void provisions and clearance to replace existing
functionality on `IfcBuildingElementProxy`". `IfcVirtualElement` gained a
`PredefinedType` of `IfcVirtualElementTypeEnum` : `BOUNDARY`, `PROVISIONFORVOID`,
`CLEARANCE`, `USERDEFINED`, `NOTDEFINED`.

Fix (IFC4.3) : replace each placeholder `IfcBuildingElementProxy` with an
`IfcVirtualElement`, set `PredefinedType` to `PROVISIONFORVOID`, `CLEARANCE`, or
`BOUNDARY` as appropriate, and keep the element in the spatial structure with the
SAME `IfcRelContainedInSpatialStructure` link. In IFC2x3 and IFC4 the legacy
proxy-with-`PROVISIONFORVOID` pattern still validates ; ALWAYS migrate it when
upgrading a file to IFC4.3.

### Pattern 6 : repair a missing or broken spatial tree

A broken tree has one or more of : no `IfcSite`, a spatial element with no
aggregation path to `IfcProject`, more than one `IfcProject`, or `IfcProject`
itself being aggregated by something.

Checks and fixes:

- WR41 on `IfcSpatialStructureElement` : "All spatial structure elements shall be
  associated (using the `IfcRelAggregates` relationship) with another spatial
  structure element, or with `IfcProject`." A site or building with an empty
  `Decomposes` inverse fails WR41. Fix : add the `IfcRelAggregates` link to its
  parent.
- `NoDecomposition` on `IfcProject` : `IfcProject.Decomposes` MUST be empty.
  Nothing aggregates the project. Fix : remove any `IfcRelAggregates` whose
  `RelatedObjects` contains the `IfcProject`.
- `IfcSingleProjectInstance` global `RULE` (IFC4, IFC4.3) : `SIZEOF(IfcProject)
  <= 1`. Fix : keep exactly one `IfcProject` and re-aggregate every site beneath
  it.
- A missing intermediate level (elements containment-linked to `IfcBuilding`
  with no `IfcBuildingStorey`) is accepted by some tools but breaks storey-based
  views. ALWAYS model the full chain Project to Site to Building/Facility to
  Storey to Space and contain physical elements at the storey or space level.

ALWAYS run the buildingSMART validation service after the repair : the `SPS`
normative rule family checks basic spatial structure for buildings.

## Reference Links

- `references/methods.md` : entity and attribute signatures, the
  `ContainedInStructure` inverse, WR31, WR41, `NoDecomposition`,
  `IfcSingleProjectInstance`, `IfcVirtualElementTypeEnum`, version differences.
- `references/examples.md` : verified STEP fragments : a correct tree, each error
  and its fix.
- `references/anti-patterns.md` : the spatial-structure mistakes and why each one
  is wrong.

### Related skills

- `ifc-core-spatial-structure` : how the spatial tree is built correctly.
- `ifc-impl-spatial-decomposition` : the authoring workflow for the tree.
- `ifc-core-relationships` : the objectified `IfcRel*` pattern, relating vs related.
- `ifc-errors-schema-validation` : `WHERE`-rule, global-`RULE`, abstract-entity errors.
- `ifc-errors-broken-references` : dangling `#id` and missing INVERSE links.
- `ifc-errors-version-mismatch` : deprecated and removed-entity errors per schema.

### Verified sources

All entity declarations, attribute types, `WHERE`-rule text (WR31, WR41,
`NoDecomposition`), the `ContainedInStructure` inverse cardinality, and the
`IfcVirtualElement` change note verified 2026-05-20 via WebFetch against the
buildingSMART sources in `SOURCES.md` : the IFC 4.3.2 specification, the IFC4
ADD2 TC1 specification, and the IFC2x3 TC1 specification.

