| name | ifc-errors-spatial-structure |
| description | 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, and the IFC4.3 IfcVirtualElement replacement for proxy placeholders. Keywords: IFC spatial structure error, orphan element, IfcRelContainedInSpatialStructure, double containment, ContainedInStructure, WR31, WR41, IfcSpatialStructureElement, IfcRelAggregates, IfcVirtualElement, IfcBuildingElementProxy, PROVISIONFORVOID, missing IfcSite, broken spatial tree, IfcSingleProjectInstance, SPS rules, "element not in model tree", "missing from quantity take-off", "nothing shows under the storey", "element has no container", how do I attach an element to a storey, why is my element invisible to facility management.
|
| license | MIT |
| compatibility | Designed for Claude Code. Requires IFC IFC2x3, IFC4, IFC4.3. |
| metadata | {"author":"OpenAEC-Foundation","version":"1.0"} |
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.