apache/beam · error · ValueError
Only one of expansion_service
Error message
Only one of expansion_service (%s) or classpath (%s) may be provided.
What it means
JavaExternalTransform.__init__ got both an explicit expansion_service and a classpath; the two are mutually exclusive ways to locate the Java transform (remote service vs. locally started service from jars), so passing both is rejected.
Solutions
- Pass only classpath jars and let Beam start the service locally
- Or pass only expansion_service (e.g. 'localhost:8097') and drop classpath
Defensive patterns
Strategy: validation
When it happens
Trigger: Thrown at sdks/python/apache_beam/transforms/external.py:617 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/e5cf2f91be07b21e.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/python/apache_beam/transforms/external.py:617
One builds these transforms just as one would in Java, e.g.::
transform = JavaExternalTransform('fully.qualified.ClassName'
)(contructorArg, ... ).builderMethod(...)
or::
JavaExternalTransform('fully.qualified.ClassName').staticConstructor(
...).builderMethod1(...).builderMethod2(...)
:param class_name: fully qualified name of the java class
:param expansion_service: (Optional) an expansion service to use. If none is
provided, a default expansion service will be started.
:param classpath: (Optional) A list paths to additional jars to place on the
expansion service classpath.
"""
def __init__(self, class_name, expansion_service=None, classpath=None):
if expansion_service and classpath:
raise ValueError(
f'Only one of expansion_service ({expansion_service}) '
f'or classpath ({classpath}) may be provided.')
self._payload_builder = JavaClassLookupPayloadBuilder(class_name)
self._classpath = classpath
self._expansion_service = expansion_service
# Beam explicitly looks for following attributes. Hence adding
# 'None' values here to prevent '__getattr__' from being called.
self.inputs = None
self._fn_api_payload = None
def __call__(self, *args, **kwargs):
self._payload_builder.with_constructor(*args, **kwargs)
return self
def __getattr__(self, name):
# Don't try to emulate special methods.
if name.startswith('__') and name.endswith('__'):
return super().__getattr__(name)View on GitHub (pinned to 12126d8942)