apache/beam · error · ValueError

Unable to install a local of Prism

Error message

Unable to install a local of Prism: "%s";
Likely Go is not installed, or a local change to Prism did not compile.
Please install Go (see https://go.dev/doc/install) to enable automatic local builds.
Alternatively provide a binary with the --prism_location flag.
Captured output:
 %s

What it means

When Prism must be built locally from source (go install), _install_from_source runs the Go toolchain and checks the captured output. If it fails — either Go is not installed or the local Prism source does not compile — the @latest fallback would fail or hide the error, so ValueError is raised immediately with the captured output.

Solutions

  1. Read the captured output in the message to identify the actual failure
  2. Install Go (https://go.dev/doc/install) and verify 'go version' works in your shell
  3. If building a local Prism change, fix the compile errors reported in the captured output
  4. Alternatively pass a prebuilt prism binary via --prism_location to skip source builds

Example fix

// before (shell)
python -m apache_beam.runners.portability.prism_runner ...   # fails, no Go
// after
# install Go, then
go version && python -m apache_beam.runners.portability.prism_runner ...
Defensive patterns

Strategy: fallback

Validate before calling

import shutil
if shutil.which('go') is None:
    raise SystemExit('Go is not installed; install from https://go.dev/doc/install or pass --prism_location <binary>')

Type guard

def go_available() -> bool:
    return shutil.which('go') is not None

Try / catch

try:
    server = PrismJobServer(options)
except ValueError as e:
    if 'Unable to install a local of Prism' in str(e):
        print(e)  # includes captured go output
        sys.exit(2)

Prevention

When it happens

Trigger: _resolve_source_path falls back to local source build (e.g. prism_location points at a local source tree, or a developer build) and the 'go install/build' subprocess exits nonzero, including when the go binary is absent.

Common situations: Go missing from PATH on CI or a fresh machine; developing a local change to Prism that has a compile error; broken GOPATH/module setup; Go toolchain too old for the Prism module's go directive.

Understand the failure class

Background: "not installed", "pip install", "required for": how missing-dependency errors surface across open-source libraries — this error's family across 34 libraries.

Related errors


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

Appendix: source

Thrown at sdks/python/apache_beam/runners/portability/prism_runner.py:422

                             env=envdict,
                             check=False)
    if process.returncode == 0:
      # Successfully installed
      return '%s/prism' % (PrismJobServer.BIN_CACHE)

    # We failed to build for some reason.
    output = process.stdout.decode("utf-8")
    if ("not in a module" not in output) and ("no required module provides"
                                              not in output):
      # This branch handles two classes of failures:
      # 1. Go isn't installed, so it needs to be installed by the Beam SDK
      #   developer.
      # 2. Go is installed, and they are building in a local version of Prism,
      #    but there was a compile error that the developer should address.
      # Either way, the @latest fallback either would fail, or hide the error,
      # so fail now.
      _LOGGER.info(output)
      raise ValueError(
          'Unable to install a local of Prism: "%s";\n'
          'Likely Go is not installed, or a local change to Prism did not '
          'compile.\nPlease install Go (see https://go.dev/doc/install) to '
          'enable automatic local builds.\n'
          'Alternatively provide a binary with the --prism_location flag.'
          '\nCaptured output:\n %s' % (version, output))

    # Go is installed and claims we're not in a Go module that has access to
    # the Prism package.

    # Fallback to using the @latest version of prism, which works everywhere.
    _LOGGER.info(
        'Installing prism from "%s@latest" into "%s".',
        PRISMPKG,
        PrismJobServer.BIN_CACHE)
    process = subprocess.run(["go", "install", PRISMPKG + "@latest"],
                             stdout=subprocess.PIPE,
                             stderr=subprocess.STDOUT,

View on GitHub (pinned to 12126d8942)