{"record":{"id":"6ce497f516abfacc","repo":"langchain-ai/deepagents","slug":"pendingnotification-self-key-r-has-primaries-p","errorCode":null,"errorMessage":"PendingNotification {self.key!r} has {primaries} primary actions; at most one is allowed","messagePattern":"PendingNotification (.+?) has (.+?) primary actions; at most one is allowed","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"libs/code/deepagents_code/notifications.py","lineNumber":132,"sourceCode":"        \"\"\"Enforce basic invariants at construction time.\n\n        Raises:\n            ValueError: If `key` is empty, `actions` is empty, or more\n                than one action is marked `primary=True`.\n        \"\"\"\n        if not self.key:\n            msg = \"PendingNotification.key must be non-empty\"\n            raise ValueError(msg)\n        if not self.actions:\n            msg = f\"PendingNotification {self.key!r} must declare at least one action\"\n            raise ValueError(msg)\n        primaries = sum(1 for a in self.actions if a.primary)\n        if primaries > 1:\n            msg = (\n                f\"PendingNotification {self.key!r} has {primaries} primary actions; \"\n                \"at most one is allowed\"\n            )\n            raise ValueError(msg)\n\n\nclass NotificationRegistry:\n    \"\"\"In-memory store of pending notifications.\n\n    Instance-scoped (one per app) so test apps don't pollute each other.\n    Owns the bidirectional key-to-toast-identity binding so callers\n    cannot accidentally desynchronize the click-routing indices.\n    \"\"\"\n\n    def __init__(self) -> None:\n        \"\"\"Initialize an empty registry.\"\"\"\n        self._entries: dict[str, PendingNotification] = {}\n        self._key_to_toast: dict[str, str] = {}\n        self._toast_to_key: dict[str, str] = {}\n\n    def add(self, notification: PendingNotification) -> None:\n        \"\"\"Register a new notification or replace an existing one with the same key.","sourceCodeStart":114,"sourceCodeEnd":150,"githubUrl":"https://github.com/langchain-ai/deepagents/blob/a1af029e6e73cb17c36bff823d227747b28e91e1/libs/code/deepagents_code/notifications.py#L114-L150","documentation":"At most one action in a `PendingNotification` may be marked `primary=True`; `__post_init__` counts primaries and raises a `ValueError` naming the key and the count when more than one is found. This enforces a single highlighted action in the UI.","triggerScenarios":"Constructing a notification whose actions list contains two or more actions with `primary=True`, often after merging action lists or copying actions from another notification.","commonSituations":"Appending a default primary action to a list that already contains one; combining actions from multiple sources without deduplicating the primary flag; a config file that marks several buttons as primary.","solutions":["Set `primary=True` on exactly one action, demoting the rest to `primary=False`","When merging lists, keep the first primary and clear the flag on the others","Add a normalization step before construction: `for i, a in enumerate(actions): a.primary = a.primary and i == first_primary_index`"],"exampleFix":"// before\nnote = PendingNotification(key=\"deploy\", actions=[Approve(primary=True), Reject(primary=True)])\n// after\nnote = PendingNotification(key=\"deploy\", actions=[Approve(primary=True), Reject(primary=False)])","handlingStrategy":"validation","validationCode":"primaries = sum(1 for a in actions if a.primary)\nif primaries > 1:\n    raise ValueError(f\"at most one primary action allowed, got {primaries}\")","typeGuard":null,"tryCatchPattern":"try:\n    note = PendingNotification(key=key, actions=actions)\nexcept ValueError as e:\n    logging.warning(\"invalid notification %r: %s\", key, e)","preventionTips":["Mark exactly one action primary when defining action sets","Normalize the primary flag when merging action lists","Encode the single-primary rule in a shared action-builder helper"],"tags":["python","validation","notifications","dataclass"],"backgroundTag":"schema-validation-failed","analyzedSha":"a1af029e6e73cb17c36bff823d227747b28e91e1","analyzedAt":"2026-08-29T11:43:24.718Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}