{"record":{"id":"39bdfaf2c0f52690","repo":"apache/beam","slug":"the-extra-package-option-expects-a-full-path-ending-with-tar","errorCode":null,"errorMessage":"The --extra_package option expects a full path ending with \".tar\", \".tar.gz\", \".whl\" or \".zip\" instead of %s","messagePattern":"The --extra_package option expects a full path ending with \"\\.tar\", \"\\.tar\\.gz\", \"\\.whl\" or \"\\.zip\" instead of (.+?)","errorType":"validation","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/runners/portability/stager.py","lineNumber":633,"sourceCode":"\n      Returns:\n        A list of ArtifactInformation of local file paths and file names\n        (no paths) for the resources staged. All the files are assumed to be\n        staged in staging_location.\n\n      Raises:\n        RuntimeError: If files specified are not found or do not have expected\n          name patterns.\n      \"\"\"\n    resources: list[beam_runner_api_pb2.ArtifactInformation] = []\n    staging_temp_dir = tempfile.mkdtemp(dir=temp_dir)\n    local_packages: list[str] = []\n    for package in extra_packages:\n      if not (os.path.basename(package).endswith('.tar') or\n              os.path.basename(package).endswith('.tar.gz') or\n              os.path.basename(package).endswith('.whl') or\n              os.path.basename(package).endswith('.zip')):\n        raise RuntimeError(\n            'The --extra_package option expects a full path ending with '\n            '\".tar\", \".tar.gz\", \".whl\" or \".zip\" instead of %s' % package)\n      if os.path.basename(package).endswith('.whl'):\n        _LOGGER.warning(\n            'The .whl package \"%s\" provided in --extra_package '\n            'must be binary-compatible with the worker runtime environment.' %\n            package)\n\n      if not os.path.isfile(package):\n        if Stager._is_remote_path(package):\n          # Download remote package.\n          _LOGGER.info(\n              'Downloading extra package: %s locally before staging', package)\n          _, last_component = FileSystems.split(package)\n          local_file_path = FileSystems.join(staging_temp_dir, last_component)\n          Stager._download_file(package, local_file_path)\n        else:\n          raise RuntimeError(","sourceCodeStart":615,"sourceCodeEnd":651,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/runners/portability/stager.py#L615-L651","documentation":"Stager._create_jar_packages' sibling _create_extra_packages validates that every --extra_package entry has basename ending in .tar, .tar.gz, .whl or .zip (the formats the Python SDK container can install). Other extensions raise this RuntimeError.","triggerScenarios":"create_job_resources with options.extra_packages containing an entry whose basename lacks one of the accepted extensions.","commonSituations":"Passing a .jar, .egg, .tar.bz2, or a directory; passing a Windows-built sdist with unexpected extension; confusion between jar_packages and extra_package options.","solutions":["Repackage the dependency as a .tar.gz sdist, .whl, .zip, or .tar and pass its full path","For Java jars use --experiment=jar_packages=... instead of extra_package","If you have a .tar.bz2, recompress to .tar.gz; for .egg, build a wheel (pip wheel) instead","Ensure the path basename (not the full string) carries the extension"],"exampleFix":"// before\n--extra_package=/libs/my-dep.egg\n// after\n--extra_package=/libs/my_dep-1.0-py3-none-any.whl","handlingStrategy":"validation","validationCode":"extra = options.view_as(SetupOptions).extra_packages or []\nbad = [p for p in extra if os.path.basename(p).rsplit('.', 1)[-1]\n       not in ('tar', 'gz', 'whl', 'zip')]\nif bad:\n    raise SystemExit(f'extra_package must be .tar/.tar.gz/.whl/.zip: {bad}')","typeGuard":"def is_extra_package(p):\n    b = os.path.basename(p)\n    return b.endswith(('.tar', '.tar.gz', '.whl', '.zip'))","tryCatchPattern":"try:\n    stager.create_and_stage_job_resources(setup_options)\nexcept RuntimeError as e:\n    if '--extra_package option expects' in str(e):\n        sys.exit(f'Repackage dependency: {e}')\n    raise","preventionTips":["Distribute Python deps as wheels or sdists (.whl/.tar.gz)","Use jar_packages for Java jars","Remember .whl extras must match the worker's platform/Python version"],"tags":["python","cli","validation","beam"],"backgroundTag":"invalid-cli-argument","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"}