{"record":{"id":"f7d86fc6d58fb015","repo":"apache/beam","slug":"parsed-object-is-not-a-chunk-instance","errorCode":null,"errorMessage":"Parsed object is not a Chunk instance","messagePattern":"Parsed object is not a Chunk instance","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/ml/rag/utils.py","lineNumber":115,"sourceCode":"      'Content': Content,\n      'Embedding': Embedding,\n      'defaultdict': defaultdict,\n      'list': list,\n      '__builtins__': {}\n  }\n\n  for raw_str in chunk_str_list:\n    try:\n      # replace \"<class 'list'>\" with actual list reference.\n      cleaned_str = re.sub(\n          r\"defaultdict\\(<class 'list'>\", \"defaultdict(list\", raw_str)\n\n      # Evaluate string in restricted environment.\n      chunk = eval(cleaned_str, safe_globals)  # pylint: disable=eval-used\n      if isinstance(chunk, Chunk):\n        parsed_chunks.append(chunk)\n      else:\n        raise ValueError(\"Parsed object is not a Chunk instance\")\n    except Exception as e:\n      raise ValueError(f\"Error parsing string:\\n{raw_str}\\n{e}\")\n\n  return parsed_chunks\n\n\ndef unpack_dataclass_with_kwargs(dataclass_instance):\n  \"\"\"Unpacks dataclass fields into a flat dict, merging kwargs with precedence.\n\n  Args:\n    dataclass_instance: Dataclass instance to unpack.\n\n  Returns:\n    dict: Flattened dictionary with kwargs taking precedence over fields.\n  \"\"\"\n  # Create a copy of the dataclass's __dict__.\n  params_dict: dict = dataclass_instance.__dict__.copy()\n","sourceCodeStart":97,"sourceCodeEnd":133,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/ml/rag/utils.py#L97-L133","documentation":"parse_chunk_strings evaluates input strings in a restricted environment and expects each parsed object to be a legacy Chunk instance. If eval() yields any other object (int, dict, list, different class), the function raises ValueError, which is then re-raised wrapped with the offending raw string.","triggerScenarios":"Passing strings that evaluate to non-Chunk objects — e.g. a plain dict, a list, a number, or an object of a class not named Chunk in the safe globals (such as EmbeddableItem or a custom class not exposed to the eval environment).","commonSituations":"Reading side-input data written by a newer pipeline that serialized EmbeddableItem instead of Chunk; typos or corrupted lines in the input file; pickled/repr'd objects of another type fed into the parser.","solutions":["Ensure each input string evaluates to a Chunk(...), e.g. \"Chunk(content=Content(text='...'), embedding=[0.1, ...])\"","Expose the correct class in the safe eval environment if using a custom Chunk subclass","Pre-validate/pre-parse the side input file and skip or fix lines that don't produce Chunk instances","Catch ValueError from parse_chunk_strings to log the offending raw_str and continue"],"exampleFix":"// before\nparse_chunk_strings([\"{'id': 1, 'text': 'hi'}\"])\n// after\nparse_chunk_strings([\"Chunk(content=Content(text='hi'), embedding=[0.1, 0.2])\"])","handlingStrategy":"try-catch","validationCode":"import ast\nfor s in raw_strings:\n    node = ast.parse(s, mode='eval')\n    if not (isinstance(node.body, ast.Call) and getattr(node.body.func, 'id', '') == 'Chunk'):\n        raise ValueError(f\"Not a Chunk literal: {s!r}\")","typeGuard":"def is_chunk_literal(s: str) -> bool:\n    import ast\n    try:\n        body = ast.parse(s, mode='eval').body\n    except SyntaxError:\n        return False\n    return isinstance(body, ast.Call) and getattr(body.func, 'id', '') == 'Chunk'","tryCatchPattern":"try:\n    chunks = parse_chunk_strings(raw_strings)\nexcept ValueError as e:\n    logging.error(\"Bad chunk side-input: %s\", e)\n    chunks = []","preventionTips":["Serialize side inputs with repr(Chunk(...)) so they eval back to Chunk","Use ast to pre-validate strings before eval-based parsing","Watch for schema drift: newer pipelines writing EmbeddableItem into legacy Chunk side inputs"],"tags":["python","rag","parsing","type-mismatch"],"backgroundTag":"type-mismatch","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-20T03:17:13.778Z"}