bytedance/deer-flow · error · MemoryManifestRevisionConflict

Expected user-memory revision {expected_revision}, found {cu

Error message

Expected user-memory revision {expected_revision}, found {current_revision}

What it means

Error "Expected user-memory revision {expected_revision}, found {current_revision}" thrown in bytedance/deer-flow.

Source

Thrown at backend/packages/harness/deerflow/agents/memory/backends/deermem/deermem/core/storage.py:728

        user_id: str | None,
        agent_name: str | None,
        upserts: list[dict[str, Any]],
        deletes: list[str],
        summaries: dict[str, Any] | None,
        expected_revision: int | None,
        delete_revisions: dict[str, int] | None = None,
        upsert_revisions: dict[str, int | None] | None = None,
    ) -> tuple[dict[str, Any], list[RetrievalNotification]]:
        """Commit only the addressed fact files plus the shared summary JSON.

        Callers hold both locks and have already run journal recovery.  This is
        deliberately not implemented as load-all/replace-all: unchanged fact
        files are neither opened for backup nor rewritten nor re-indexed.
        """
        current_memory = self._load_memory_file(path)
        current_revision = int((current_memory or {}).get("revision") or 0)
        if expected_revision is not None and expected_revision != current_revision:
            raise MemoryManifestRevisionConflict(f"Expected user-memory revision {expected_revision}, found {current_revision}")
        if (upserts or deletes) and agent_name is None:
            raise ValueError("agent_name is required for fact repository changes")

        scope = _scope_dict(user_id, agent_name)
        prepared: dict[str, tuple[dict[str, Any], dict[str, Any] | None, Path]] = {}
        for incoming in upserts:
            if not isinstance(incoming, dict):
                raise ValueError("change_set.upserts must contain fact objects")
            candidate = copy.deepcopy(incoming)
            candidate["id"] = str(candidate.get("id") or f"fact_{uuid.uuid4().hex}")
            fact_id = candidate["id"]
            if fact_id in prepared:
                raise ValueError(f"Duplicate fact id {fact_id!r} in upserts")
            if agent_name is None:  # guarded above
                raise ValueError("agent_name is required for fact repository changes")
            existing, fact_path = self._read_fact(path, fact_id, user_id=user_id, agent_name=agent_name)
            if upsert_revisions is not None and fact_id in upsert_revisions:
                expected_fact_revision = upsert_revisions[fact_id]

View on GitHub (pinned to 1dd6ba1acb)

Solutions

  1. Re-read the current memory state and retry the change with the current revision (optimistic concurrency).
  2. If revisions keep diverging, check for multiple writers to the same memory scope.

When it happens

Trigger: Thrown at backend/packages/harness/deerflow/agents/memory/backends/deermem/deermem/core/storage.py:728 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of bytedance/deer-flow@1dd6ba1acb (2026-08-14). Data as JSON: /api/errors/6d7fdedf164a2d79. Report an issue: GitHub.