{"record":{"id":"787cd2389ebb2ef9","repo":"bytedance/deer-flow","slug":"legacy-fact-in-source-path-is-not-an-object","errorCode":null,"errorMessage":"Legacy fact in {source_path} is not an object","messagePattern":"Legacy fact in (.+?) is not an object","errorType":"exception","errorClass":"MemoryStorageCorruption","httpStatus":null,"severity":"error","filePath":"backend/packages/harness/deerflow/agents/memory/backends/deermem/deermem/core/storage.py","lineNumber":900,"sourceCode":"                    canonical=migrated_summaries[section],\n                    legacy=legacy_memory.get(section, {}),\n                    section=section,\n                    legacy_path=legacy_path,\n                )\n\n        upserts: list[dict[str, Any]] = []\n        pending: dict[str, dict[str, Any]] = {}\n        for source_path, source_memory in sources:\n            source_document = self._document_from_memory_file(\n                source_memory,\n                source_path,\n                agent_name,\n                user_id=user_id,\n                allow_legacy_facts=True,\n            )\n            for raw_fact in source_document.get(\"facts\", []):\n                if not isinstance(raw_fact, dict):\n                    raise MemoryStorageCorruption(f\"Legacy fact in {source_path} is not an object\")\n                candidate = _normalize_fact(raw_fact, scope=_scope_dict(user_id, agent_name))\n                existing, _ = self._read_fact(path, candidate[\"id\"], user_id=user_id, agent_name=agent_name)\n                if existing is not None:\n                    if not self._migration_equivalent(candidate, existing):\n                        raise MemoryStorageCorruption(f\"Fact migration conflict for {candidate['id']!r}\")\n                    continue\n                previous = pending.get(candidate[\"id\"])\n                if previous is not None:\n                    if not self._migration_equivalent(candidate, previous):\n                        raise MemoryStorageCorruption(f\"Fact migration conflict for {candidate['id']!r}\")\n                    continue\n                pending[candidate[\"id\"]] = candidate\n                upserts.append(candidate)\n\n        # Migration is intentionally one-way for the running application.\n        # Preserve every destructive v1 JSON source before the first v2 write;\n        # a failed/mismatched backup aborts while all source data is untouched.\n        for source_path, _ in sources:","sourceCodeStart":882,"sourceCodeEnd":918,"githubUrl":"https://github.com/bytedance/deer-flow/blob/1dd6ba1acb03700589994b0366c5d1c7d05e2eff/backend/packages/harness/deerflow/agents/memory/backends/deermem/deermem/core/storage.py#L882-L918","documentation":"Error \"Legacy fact in {source_path} is not an object\" thrown in bytedance/deer-flow.","triggerScenarios":"Thrown at backend/packages/harness/deerflow/agents/memory/backends/deermem/deermem/core/storage.py:900 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Fix the legacy fact file so it contains a JSON object.","Remove the malformed entry from the legacy source and retry migration."],"exampleFix":null,"handlingStrategy":null,"validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"1dd6ba1acb03700589994b0366c5d1c7d05e2eff","analyzedAt":"2026-08-14T21:20:34.804Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}