666ghj/MiroFish · error · RuntimeError

Zep graph.add returned no episode UUID

Error message

Zep graph.add returned no episode UUID

What it means

Raised in ZepGraphMemoryUpdater after a successful-looking call to Zep Cloud's graph.add: the returned episode object exposes neither a 'uuid_' nor a 'uuid' attribute, so the updater cannot track the episode for later ingestion polling. Because graph.add is not idempotent, the updater deliberately fails closed instead of retrying — replaying an ambiguous response could duplicate extracted facts in the knowledge graph.

Source

Thrown at backend/app/services/zep_graph_memory_updater.py:524

                        "last_round": max(a.round_num for a in payload_activities),
                        "agent_ids": ",".join(
                            str(value)
                            for value in sorted({a.agent_id for a in payload_activities})
                        ),
                        "action_types": ",".join(
                            value
                            for value in sorted({a.action_type for a in payload_activities})
                            if value
                        ) or "unknown",
                    },
                )

                episode_uuid = (
                    getattr(episode, "uuid_", None)
                    or getattr(episode, "uuid", None)
                )
                if not episode_uuid:
                    raise RuntimeError("Zep graph.add returned no episode UUID")
                self._pending_episode_uuids.append(str(episode_uuid))
                self._total_sent += 1
                self._total_items_sent += len(payload_activities)
                display_name = self._get_platform_display_name(platform)
                logger.info(f"成功批量发送 {len(payload_activities)} 条{display_name}活动到图谱 {self.graph_id}")
                logger.debug(f"批量内容预览: {combined_text[:200]}...")

            except Exception as e:
                # graph.add has no idempotency key. Replaying an ambiguous
                # response can duplicate extracted facts, so fail closed and
                # surface the incomplete batch to SimulationRunner.
                logger.error(f"批量发送到Zep失败,未自动重放非幂等写入: {e}")
                self._failed_count += 1
                self._failed_batches.append({
                    "platform": platform,
                    "activities": payload_activities,
                    "error": str(e),
                })

View on GitHub (pinned to b5b53acc57)

Solutions

  1. Log the raw episode object (repr/dir) at the failure site to see which fields Zep actually returned
  2. Pin the zep-cloud SDK to a tested version and check its changelog for episode response changes
  3. If the field was renamed, extend the getattr chain in zep_graph_memory_updater.py:519-522 to include the new attribute name
  4. Do NOT add automatic retry around graph.add — it is non-idempotent; a retry can duplicate extracted facts
  5. Verify the graph_id exists and the API key has write permission on that graph

Example fix

# before
episode_uuid = (
    getattr(episode, "uuid_", None)
    or getattr(episode, "uuid", None)
)
if not episode_uuid:
    raise RuntimeError("Zep graph.add returned no episode UUID")

# after
episode_uuid = (
    getattr(episode, "uuid_", None)
    or getattr(episode, "uuid", None)
)
if not episode_uuid:
    logger.error("Unexpected graph.add response: %r", episode)
    raise RuntimeError("Zep graph.add returned no episode UUID")
Defensive patterns

Strategy: try-catch

Try / catch

try:
    episode = client.graph.add(...)
except RuntimeError:
    # fail closed: do NOT replay graph.add (non-idempotent); surface to runner
    raise

Prevention

When it happens

Trigger: Calling client.graph.add(...) (batch of platform activities) where the server response body omits the episode UUID field, or a Zep Cloud SDK version whose episode model names the field differently than uuid_/uuid. Also possible if the API silently changed its response schema or returned a degraded/error object that still parsed.

Common situations: Zep Cloud API/SDK version drift (response schema change), a misconfigured graph_id causing a partial response, or a proxy/gateway stripping response fields. Typically surfaces mid-simulation while flushing buffered activities.

Related errors


AI-assisted analysis of 666ghj/MiroFish@b5b53acc57 (2026-08-14). Data as JSON: /api/errors/5d7127d5244cb861. Report an issue: GitHub.