{"record":{"id":"ceb63217b370f38f","repo":"FoundationAgents/MetaGPT","slug":"invalid-object-json-in-metadata-node-metadata","errorCode":null,"errorMessage":"Invalid object json in metadata: {node.metadata}, error: {e}","messagePattern":"Invalid object json in metadata: (.+?), error: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"metagpt/rag/rankers/object_ranker.py","lineNumber":49,"sourceCode":"        query_bundle: Optional[QueryBundle] = None,\n    ) -> list[NodeWithScore]:\n        \"\"\"Postprocess nodes.\"\"\"\n        if query_bundle is None:\n            raise ValueError(\"Missing query bundle in extra info.\")\n\n        if not nodes:\n            return []\n\n        self._check_metadata(nodes[0].node)\n\n        sort_key = lambda node: json.loads(node.node.metadata[\"obj_json\"])[self.field_name]\n        return self._get_sort_func()(self.top_n, nodes, key=sort_key)\n\n    def _check_metadata(self, node: ObjectNode):\n        try:\n            obj_dict = json.loads(node.metadata.get(\"obj_json\"))\n        except Exception as e:\n            raise ValueError(f\"Invalid object json in metadata: {node.metadata}, error: {e}\")\n\n        if self.field_name not in obj_dict:\n            raise ValueError(f\"Field '{self.field_name}' not found in object: {obj_dict}\")\n\n    def _get_sort_func(self):\n        return heapq.nlargest if self.order == \"desc\" else heapq.nsmallest\n","sourceCodeStart":31,"sourceCodeEnd":56,"githubUrl":"https://github.com/FoundationAgents/MetaGPT/blob/11cdf466d042aece04fc6cfd13b28e1a70341b1f/metagpt/rag/rankers/object_ranker.py#L31-L56","documentation":"ObjectSortPostprocessor._check_metadata json-parses the node's metadata[\"obj_json\"] field before sorting; any exception during json.loads (missing key returns None, malformed JSON, non-string value) is re-raised as this ValueError, echoing the whole metadata dict and the underlying parse error.","triggerScenarios":"Nodes indexed into the vector store whose metadata lacks a valid obj_json entry, or whose obj_json is truncated/invalid JSON (e.g. built with str(dict) instead of json.dumps, or corrupted during ingestion).","commonSituations":"Custom ingestion code storing objects with str(obj) instead of json.dumps(obj); metadata size limits in the vector store silently truncating long JSON; nodes that came from a different index schema without obj_json.","solutions":["Fix ingestion to store json.dumps(obj) under metadata key \"obj_json\" exactly","Re-index the affected documents after correcting the metadata producer","Inspect node.metadata before retrieval to confirm obj_json parses: json.loads(node.metadata[\"obj_json\"])"],"exampleFix":"// before\nnode.metadata[\"obj_json\"] = str(my_dict)  # single quotes -> JSONDecodeError later\n\n// after\nimport json\nnode.metadata[\"obj_json\"] = json.dumps(my_dict)","handlingStrategy":"validation","validationCode":"import json\nobj = node.metadata.get(\"obj_json\")\nassert isinstance(obj, str), \"obj_json missing from node metadata\"\njson.loads(obj)  # raises early, at ingestion time, with full control","typeGuard":"import json\n\ndef has_valid_obj_json(node) -> bool:\n    raw = node.node.metadata.get(\"obj_json\")\n    if not isinstance(raw, str):\n        return False\n    try:\n        json.loads(raw)\n        return True\n    except (TypeError, ValueError):\n        return False","tryCatchPattern":"try:\n    nodes = ranker.postprocess_nodes(nodes, query_bundle=qb)\nexcept ValueError as e:\n    if \"Invalid object json\" in str(e):\n        nodes = [n for n in nodes if has_valid_obj_json(n)]  # drop corrupt nodes, retry once\n    else:\n        raise","preventionTips":["Write obj_json with json.dumps only, never str(dict)","Validate json.loads round-trip during ingestion before nodes enter the index","Watch metadata size limits in the vector store to avoid silent truncation"],"tags":["rag","metadata","json","data-quality"],"backgroundTag":null,"analyzedSha":"11cdf466d042aece04fc6cfd13b28e1a70341b1f","analyzedAt":"2026-08-14T23:20:02.994Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}