apache/beam · error · ValueError

specifies an invalid destination ' '. Please make sure the…

Error message

{message} specifies an invalid destination '{dest}'. Please make sure the destination is an existing directory.

What it means

validate_sdks_destinations verifies that each destination path exists as a directory under PYTHON_SDK_ROOT. If os.path.isdir fails for the configured destination, ValueError reports the invalid destination so wrappers are not written to nonexistent locations.

Solutions

  1. Fix the destination path in the YAML so it matches an existing directory under sdks/python.
  2. Create the missing directory if it is genuinely the intended output location (git add with a placeholder if needed).
  3. Re-run gen_xlang_wrappers.py after correcting.

Example fix

// before
  destinations:
    python: sdks/python/apache_beam/transforms/xlang
// after
  destinations:
    python: sdks/python/apache_beam/transforms
Defensive patterns

Strategy: validation

Validate before calling

import os
from gen_xlang_wrappers import PYTHON_SDK_ROOT
for svc in services:
    for sdk, dest in svc['destinations'].items():
        assert os.path.isdir(os.path.join(PYTHON_SDK_ROOT, *dest.split('/'))), \
            f"destination does not exist: {dest}"

Type guard

def destination_exists(dest):
    import os
    from gen_xlang_wrappers import PYTHON_SDK_ROOT
    return os.path.isdir(os.path.join(PYTHON_SDK_ROOT, *dest.split('/')))

Try / catch

try:
    generate_transforms_config(services_yaml, ...)
except ValueError as e:
    if 'invalid destination' in str(e):
        print('Fix the destination path or create the directory')

Prevention

When it happens

Trigger: A destinations entry maps an SDK to a path that does not exist under sdks/python (wrong path, renamed directory, or created only after generation) during generate_transforms_config.

Common situations: Directory restructures that invalidate configured paths; typos in destination paths; pointing at directories outside sdks/python.

Related errors


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/7613574b8ad2fa40. Report an issue: GitHub.

Appendix: source

Thrown at sdks/python/gen_xlang_wrappers.py:201

        f"# configuration in {input_services.replace(PROJECT_ROOT, '')}.\n")
    f.write("# Refer to gen_xlang_wrappers.py for more info.\n")
    dt = datetime.datetime.now().date()
    f.write(f"#\n# Last updated on: {dt}\n\n")
    yaml.dump(transform_list, f)
  logging.info("Successfully wrote transform configs to file: %s", output_file)


def validate_sdks_destinations(sdk, dest, service, identifier=None):
  if identifier:
    message = f"Identifier '{identifier}'"
  else:
    message = f"Service '{service}'"
  if sdk not in SUPPORTED_SDK_DESTINATIONS:
    raise ValueError(
        message + " specifies a destination for an invalid SDK:"
        f" '{sdk}'. The supported SDKs are {SUPPORTED_SDK_DESTINATIONS}")
  if not os.path.isdir(os.path.join(PYTHON_SDK_ROOT, *dest.split('/'))):
    raise ValueError(
        message + f" specifies an invalid destination '{dest}'."
        " Please make sure the destination is an existing directory.")


def pretty_type(tp):
  """
  Takes a type and returns a tuple containing a pretty string representing it
  and a bool signifying if it is nullable or not.

  For optional types, the contained type is unwrapped and returned. This does
  not recurse however, so inner Optional types are not affected.
  E.g. the input typing.Optional[typing.Dict[int, typing.Optional[str]]] will
  return (Dict[int, Union[str, NoneType]], True)
  """
  nullable = False
  if (typing.get_origin(tp) is Union and type(None) in typing.get_args(tp)):
    nullable = True
    # only unwrap if it's a single nullable type. if the type is truly a union

View on GitHub (pinned to 12126d8942)