apache/beam · error · RuntimeError

The --experiment='jar_packages=' option expects a full path

Error message

The --experiment='jar_packages=' option expects a full path ending with ".jar" instead of %s

What it means

For --experiment='jar_packages=...', Stager._create_jar_packages validates each entry's basename ends with '.jar'. Anything else (zip, path without extension, directory) raises this RuntimeError before any existence check.

Source

Thrown at sdks/python/apache_beam/runners/portability/stager.py:573

      jar_packages, temp_dir) -> list[beam_runner_api_pb2.ArtifactInformation]:
    """Creates a list of local jar packages for Java SDK Harness.

    :param jar_packages: Ordered list of local paths to jar packages to be
      staged. Only packages on localfile system and GCS are supported.
    :param temp_dir: Temporary folder where the resource building can happen.
    :return: A list of tuples of local file paths and file names (no paths) for
      the resource staged. All the files are assumed to be staged in
      staging_location.
    :raises:
      RuntimeError: If files specified are not found or do not have expected
        name patterns.
    """
    resources: list[beam_runner_api_pb2.ArtifactInformation] = []
    staging_temp_dir = tempfile.mkdtemp(dir=temp_dir)
    local_packages: list[str] = []
    for package in jar_packages:
      if not os.path.basename(package).endswith('.jar'):
        raise RuntimeError(
            'The --experiment=\'jar_packages=\' option expects a full path '
            'ending with ".jar" instead of %s' % package)

      if not os.path.isfile(package):
        if Stager._is_remote_path(package):
          # Download remote package.
          _LOGGER.info(
              'Downloading jar package: %s locally before staging', package)
          _, last_component = FileSystems.split(package)
          local_file_path = FileSystems.join(staging_temp_dir, last_component)
          Stager._download_file(package, local_file_path)
        else:
          raise RuntimeError(
              'The file %s cannot be found. It was specified in the '
              '--experiment=\'jar_packages=\' command line option.' % package)
      else:
        local_packages.append(package)

View on GitHub (pinned to 12126d8942)

Solutions

  1. Ensure each jar_packages entry is a full path/URL whose basename ends with .jar
  2. Convert Maven coordinates to the actual jar URL/path
  3. Strip whitespace/query parameters from the entry
  4. Package other dependency types as jars or use extra_packages for tar/whl/zip Python packages

Example fix

// before
--experiment=jar_packages=/libs/my-lib.zip
// after
--experiment=jar_packages=/libs/my-lib.jar
Defensive patterns

Strategy: validation

Validate before calling

packages = options.view_as(SetupOptions).jar_packages or []
bad = [p for p in packages if not os.path.basename(p).endswith('.jar')]
if bad:
    raise SystemExit(f'jar_packages must end with .jar: {bad}')

Type guard

def is_jar_package(p): return isinstance(p, str) and os.path.basename(p).endswith('.jar')

Try / catch

try:
    stager.create_and_stage_job_resources(setup_options)
except RuntimeError as e:
    if "jar_packages=' option expects a full path" in str(e):
        sys.exit(f'Fix jar_packages entry: {e}')
    raise

Prevention

When it happens

Trigger: create_job_resources with options.jar_packages containing an item whose basename does not end with .jar.

Common situations: Passing a fat zip or an .aar; passing a Maven coordinate instead of a path; trailing whitespace or query string on the URL; accidentally passing a directory.

Understand the failure class

Background: "Unknown argument", "Invalid value", and "must be one of": invalid CLI argument errors explained — this error's family across 35 libraries.

Related errors


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