liabru/matter-js · warning
Composite.add: skipped adding a compound body part (you must
Error message
Composite.add: skipped adding a compound body part (you must add its parent instead)
What it means
Composite.add refuses to add an individual part of a compound body. Compound parts are internally linked to their parent (part.parent !== part); adding a part directly would corrupt collision and position bookkeeping, so Matter.js warns and skips the add instead. You must add the parent Body created by Body.create({ parts: [...] }).
Source
Thrown at src/body/Composite.js:104
* @method add
* @param {composite} composite
* @param {object|array} object A single or an array of body(s), constraint(s) or composite(s)
* @return {composite} The original composite with the objects added
*/
Composite.add = function(composite, object) {
var objects = [].concat(object);
Events.trigger(composite, 'beforeAdd', { object: object });
for (var i = 0; i < objects.length; i++) {
var obj = objects[i];
switch (obj.type) {
case 'body':
// skip adding compound parts
if (obj.parent !== obj) {
Common.warn('Composite.add: skipped adding a compound body part (you must add its parent instead)');
break;
}
Composite.addBody(composite, obj);
break;
case 'constraint':
Composite.addConstraint(composite, obj);
break;
case 'composite':
Composite.addComposite(composite, obj);
break;
case 'mouseConstraint':
Composite.addConstraint(composite, obj.constraint);
break;
}
}
View on GitHub (pinned to acb99b6f87)
Solutions
- Add the parent body: Composite.add(world, parentBody).
- If iterating, skip parts where part.parent !== part (parts[0] is the parent).
- If you actually want separate bodies, create them individually rather than as compound parts.
Example fix
// before
for (const part of compoundBody.parts) {
Composite.add(world, part); // warns for non-root parts
}
// after
Composite.add(world, compoundBody); // add the parent only Defensive patterns
Strategy: validation
Validate before calling
function isRootBody(b) { return b && b.type === 'body' && b.parent === b; }
if (isRootBody(candidate)) Composite.add(world, candidate); Type guard
function isCompoundPart(body) {
return Boolean(body && body.parent && body.parent !== body);
} Prevention
- Always add the parent body returned by Body.create({ parts: [...] })
- Remember body.parts[0] is the parent; parts[1..] are children
- Skip elements where part.parent !== part when iterating parts
- Never serialize/re-add bodies by iterating parts
When it happens
Trigger: Iterating over body.parts and calling Composite.add(world, part) for each; accessing body.parts (which includes the parent at index 0 and parts from index 1) and passing any element whose parent !== itself.
Common situations: Building multi-shape bodies then copying parts into the world; cloning/serializing bodies by iterating parts; helper utilities that add every body object they find.
Related errors
AI-assisted analysis of liabru/matter-js@acb99b6f87 (2026-09-02).
Data as JSON: /api/errors/237182b97393c0eb.
Report an issue: GitHub.