{"record":{"id":"8dd5efcd4d9fab7e","repo":"apache/beam","slug":"qual-name-parts-too-long","errorCode":null,"errorMessage":"Qual name parts too long","messagePattern":"Qual name parts too long","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/internal/code_object_pickler.py","lineNumber":216,"sourceCode":"\ndef _search_function(\n    callable: types.FunctionType,\n    node: types.FunctionType,\n    qual_name_parts: list[str]):\n  \"\"\"Searches a function to create a code object identifier.\n\n  Args:\n    callable: The callable object to search for.\n    node: The function to search within.\n    qual_name_parts: The list of qual name parts.\n\n  Returns:\n    The code object identifier, or None if not found.\n  \"\"\"\n  first_part = qual_name_parts[0]\n  if (node.__code__ == callable.__code__):\n    if len(qual_name_parts) > 1:\n      raise ValueError('Qual name parts too long')\n    return '__code__'\n  # If first part is '<locals>' then the code object is in a local variable\n  # so we should add __code__ to the path to indicate that we are entering\n  # the code object of the function.\n  if first_part == '<locals>':\n    return _extend_path(\n        '__code__', _search(callable, node.__code__, qual_name_parts))\n\n\ndef _search_code(\n    callable: types.FunctionType,\n    node: types.CodeType,\n    qual_name_parts: list[str]):\n  \"\"\"Searches a code object to create a code object identifier.\n\n  Args:\n    callable: The callable to search for.\n    node: The code object to search within.","sourceCodeStart":198,"sourceCodeEnd":234,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/internal/code_object_pickler.py#L198-L234","documentation":"Beam's code_object_pickler reconstructs code objects by walking __qualname__ parts. In _search_function, when the current attribute is __code__, the qual-name path must terminate; if more parts remain, it raises ValueError('Qual name parts too long'), meaning the identifier path does not correspond to a valid function-code nesting.","triggerScenarios":"Resolving an identifier whose qual name has extra segments after __code__ — i.e. a malformed/ambiguous identifier produced for a nested or unusual callable during pickling of a pipeline's callables.","commonSituations":"Pickling deeply nested local functions or classes where generated qual-name paths don't match the real object structure; dynamic code objects (exec/compile) with synthetic qualnames.","solutions":["Define the pickled callables at module level instead of deep nesting.","Avoid exec/compile-generated code with synthetic qualnames in pickled transforms.","Catch ValueError and fall back to standard cloudpickle (dill/cloudpickle pickling) for that callable.","If caused by the pickler itself, report/upgrade apache_beam version."],"exampleFix":"// before\nclass Outer:\n    def make(self):\n        def inner(x): return x  # deep nested qualname path\n        return inner\nMap(Outer().make())\n// after\ndef inner(x): return x  # module-level\nMap(inner)","handlingStrategy":"try-catch","validationCode":"if len(fn.__qualname__.split('.')) > 6:\n    raise ValueError('qualname too deep for code-object pickling; hoist to module level')","typeGuard":"def has_simple_qualname(fn) -> bool:\n    return getattr(fn, '__qualname__', '').count('.') <= 2","tryCatchPattern":"try:\n    pickled = beam_pickler.dumps(fn)\nexcept ValueError as e:\n    if 'Qual name parts too long' in str(e):\n        pickled = cloudpickle.dumps(fn)\n    else:\n        raise","preventionTips":["Define transform callables at module level.","Avoid exec/compile-generated code in pipelines.","Limit function nesting depth in DoFns."],"tags":["python","apache-beam","code-object","pickling"],"backgroundTag":"invalid-identifier-format","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}