HKUDS/Vibe-Trading · error · ValueError

entity {self.entity_id!r} cannot be its own parent

Error message

entity {self.entity_id!r} cannot be its own parent

What it means

Entity.__post_init__ rejects entities whose parent_id equals their own entity_id, since an entity cannot be its own parent in the hierarchy. This guard prevents trivially circular self-referencing trees.

Source

Thrown at agent/src/entities/models.py:178

        """Validate identifiers and coerce ``entity_type`` to its enum member.

        Raises:
            ValueError: If ``entity_id`` is blank or ``entity_type`` is unknown.
        """
        cleaned = self.entity_id.strip() if isinstance(self.entity_id, str) else ""
        if not cleaned:
            raise ValueError("entity_id is required and cannot be empty")
        object.__setattr__(self, "entity_id", cleaned)
        object.__setattr__(self, "name", self.name.strip() if self.name else "")
        try:
            object.__setattr__(self, "entity_type", EntityType(self.entity_type))
        except ValueError as exc:
            valid = ", ".join(member.value for member in EntityType)
            raise ValueError(
                f"unknown entity_type {self.entity_type!r}; expected one of: {valid}"
            ) from exc
        if self.parent_id is not None and self.parent_id == self.entity_id:
            raise ValueError(f"entity {self.entity_id!r} cannot be its own parent")


@dataclass(frozen=True)
class Instrument:
    """Base class for anything that can be held and analysed.

    Subclasses add asset-class specifics; they may only add fields *with*
    defaults, because the base already declares defaulted fields.

    Attributes:
        instrument_id: Stable identifier, e.g. an ISIN, a ticker, or a local key.
        currency: Required ISO-style currency code of this instrument's cash
            flows. Normalized to uppercase.
        name: Human-readable name.
        issuer: The entity on the hook for the instrument's obligations.
        inception_date: First date the instrument existed, when known.
    """

View on GitHub (pinned to 80ffdda44c)

Solutions

  1. Set parent_id=None for root/top-level entities instead of self
  2. Audit the source data for rows where parent == child and drop or null them before constructing objects
  3. If ids were remapped, re-run parent resolution after remapping so parents and children use the new id space

Example fix

# before
Entity(entity_id='acme', entity_type='company', parent_id='acme')

# after
Entity(entity_id='acme', entity_type='company', parent_id=None)
Defensive patterns

Strategy: validation

Validate before calling

iid = row['entity_id'].strip()
parent = (row.get('parent_id') or '').strip() or None
if parent == iid:
    parent = None  # root entity
entity = Entity(entity_id=iid, entity_type=t, parent_id=parent)

Try / catch

try:
    Entity(entity_id=iid, entity_type=t, parent_id=parent)
except ValueError as exc:
    if 'cannot be its own parent' in str(exc):
        parent = None
        entity = Entity(entity_id=iid, entity_type=t, parent_id=None)
    else:
        raise

Prevention

When it happens

Trigger: Creating an Entity where parent_id is set to the same value as entity_id (e.g. Entity(entity_id='acme', parent_id='acme')). Also occurs after id normalization/aliasing makes two originally distinct ids equal.

Common situations: Bulk imports where a self-referencing row exists in a CSV; upstream id remapping or deduplication that maps a parent onto the child itself; defaulting parent_id to entity_id as a placeholder.

Related errors


AI-assisted analysis of HKUDS/Vibe-Trading@80ffdda44c (2026-08-28). Data as JSON: /api/errors/6f28f63f8180808b. Report an issue: GitHub.