Group membership removal is broken — mandala_group_inheritance reads a non-existent data field
Area: Group collections / mandala_group_inheritance / access control Raised during: Session 2026-07-10 (1b.1 — testing the Redis visibility-token membership-change hook) Jira: (add when available) Priority: High — affects already-merged 1b.2 functionality (PR #27), not just 1b.1
What we found
Group::removeMember($account) — and therefore any code path that removes a
user from a collection/subcollection group — currently throws on any
collection whose membership-cascade hook runs:
InvalidArgumentException: Field data is unknown.
in ContentEntityBase->getTranslatedField() (ContentEntityBase.php:630)
in SqlContentEntityStorage->delete()
Confirmed the module is the cause by disabling mandala_group_inheritance
and retrying the identical delete — it succeeds cleanly with the module off.
Re-enabling reproduces the failure every time.
Root cause
mandala_group_inheritance_group_relationship_delete() →
_mandala_group_inheritance_cascade_member_remove() reads
$relationship->get('data') to check the _inherited flag (the mechanism
meant to retain sub-only members when cascading a removal from the parent
collection — see the module's own docblock). But group_relationship has
no data field at all in this codebase's Group module version:
getFieldStorageDefinitions('group_relationship') // no 'data' key, at any bundle
Confirmed at both the entity-type-storage level (no data field exists for
group_relationship full stop) and the bundle level (collection-group_membership).
This means:
- The
_inheritedflag has never actually been stored anywhere. The corresponding write path —addMember($account, ['_inherited' => TRUE])in_mandala_group_inheritance_cascade_member_add()andmandala_group_inheritance_group_insert()— silently drops the_inheritedkey on entity creation rather than erroring (Drupal doesn't strictly validate unknown array keys passed tocreate()), so the sub-only retention feature described in the module's docblock has never functioned, in either direction. - Any membership removal that reaches this code throws, because unlike
the create path,
->get('data')is a strict field lookup that errors on an undefined field name.Group::removeMember()on acollectionis therefore currently unusable for any collection with subcollections.
Why this wasn't caught in 1b.2
The 1b.2 session's verification (per the sprint doc) exercised counts,
private-collection access denial, and the membership cascade-add path —
not a real removal. The add path masks the bug (silently drops the flag
instead of erroring), so nothing failed until a removeMember() call was
actually made.
What needs to happen
Either:
- Add a real data field to the group_relationship entity/bundles (base
field or per-bundle config field) so the _inherited flag can actually be
stored and read, or
- Replace the flag mechanism entirely — e.g. track "direct vs. cascaded"
membership via a dedicated boolean field on the relationship, or by
diffing group membership rosters instead of a stored flag.
Either way, _mandala_group_inheritance_cascade_member_remove() needs a
real fix before any collection membership can be safely removed, and the
"sub-only retention" behavior needs actual test coverage exercising
removal, not just addition.
Cross-references
- ADR 011 — Option D, visibility + membership inheritance (the feature this bug breaks)
mandala_group_inheritance.module—_mandala_group_inheritance_cascade_member_remove()