apache/beam · error · ValueError
Unknown access pattern
Error message
Unknown access pattern: '%s'
What it means
When constructing the grouping table for a transform, ExecutionState (fn_api_runner execution.py) inspects the side-input access pattern's URN. Only UNION (merge) and MULTIMAP side-input access patterns are supported; any other URN means the runner cannot interpret how the input will be accessed, so a ValueError is raised at construction time.
Solutions
- Check which access pattern URN the failing transform declares and switch to a supported side-input type (multimap or merge-compatible view).
- Upgrade apache-beam so the runner recognizes the access pattern URN (new URNs are added over time).
- If using cross-language transforms, verify both SDKs/harnesses agree on supported side-input access patterns.
- Fall back to a different runner (e.g. DirectRunner/FlinkRunner) that supports the access pattern, or restructure the pipeline to avoid the unsupported side input.
Example fix
# before # pipeline uses an unsupported side-input view type with fn_api_runner result = p | ReadUnsupportedView() # after # use a supported side input, e.g. AsDict/AsMultimap style access result = p | "read" >> beam.Map(lambda x, side: ..., side=beam.pvalue.AsDict(side_pcoll))
Defensive patterns
Strategy: validation
Validate before calling
SUPPORTED = {'beam:side_input:multimap:v1', 'beam:side_input:union:v1'}
if access_pattern.urn not in SUPPORTED:
raise ValueError('unsupported side input access pattern: %s' % access_pattern.urn) Type guard
def side_input_supported(access_pattern):
return access_pattern.urn in {
'beam:side_input:multimap:v1',
'beam:side_input:union:v1',
} Try / catch
try:
state = ExecutionState(...)
except ValueError as e:
if 'Unknown access pattern' in str(e):
raise UnsupportedSideInputError(e) # fall back to another runner
raise Prevention
- Stick to side-input types the FnApiRunner documents as supported (multimap views).
- Keep SDK versions aligned in cross-language pipelines so access-pattern URNs match.
- Pin apache-beam to a version whose runner handles the URNs your pipeline emits.
- Test pipelines on the FnApiRunner early to surface unsupported access patterns before deployment.
When it happens
Trigger: A pipeline whose transform declares a side-input access pattern URN other than common_urns.side_inputs.MULTIMAP (or the merge/UNION variant handled in the preceding branch) while running under the fn_api_runner — e.g. an unsupported ITERABLE/MULTIACCESS or newly-added access pattern URN.
Common situations: Using side-input types the FnApiRunner does not yet support (e.g. certain view types); version mismatch between SDKs in cross-language pipelines where one SDK emits an access pattern URN the Python runner lacks a branch for; custom transforms declaring custom access patterns.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- BoundedWindow unsupported in
- Cannot access fire timestamp outside of @OnTimer method.
- Cannot access OnTimerContext outside of @OnTimer methods.
- Cannot access OnWindowExpirationContext outside of…
- Cannot access time domain outside of @ProcessTimer method.
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/f325364aa1e0c77b.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/python/apache_beam/runners/portability/fn_api_runner/execution.py:307
class WindowGroupingBuffer(object):
"""Used to partition windowed side inputs."""
def __init__(
self,
access_pattern: beam_runner_api_pb2.FunctionSpec,
coder: WindowedValueCoder) -> None:
# Here's where we would use a different type of partitioning
# (e.g. also by key) for a different access pattern.
if access_pattern.urn == common_urns.side_inputs.ITERABLE.urn:
self._kv_extractor = lambda value: ('', value)
self._key_coder: coders.Coder = coders.SingletonCoder('')
self._value_coder = coder.wrapped_value_coder
elif access_pattern.urn == common_urns.side_inputs.MULTIMAP.urn:
self._kv_extractor = lambda value: value
self._key_coder = coder.wrapped_value_coder.key_coder()
self._value_coder = (coder.wrapped_value_coder.value_coder())
else:
raise ValueError("Unknown access pattern: '%s'" % access_pattern.urn)
self._windowed_value_coder = coder
self._window_coder = coder.window_coder
self._values_by_window: collections.defaultdict[
tuple[str, BoundedWindow], list[Any]] = collections.defaultdict(list)
def append(self, elements_data: bytes) -> None:
input_stream = create_InputStream(elements_data)
while input_stream.size() > 0:
windowed_val_coder_impl: WindowedValueCoderImpl = (
self._windowed_value_coder.get_impl())
windowed_value = windowed_val_coder_impl.decode_from_stream(
input_stream, True)
key, value = self._kv_extractor(windowed_value.value)
for window in windowed_value.windows:
self._values_by_window[key, window].append(value)
def encoded_items(self) -> Iterator[tuple[bytes, bytes, bytes, int]]:
value_coder_impl = self._value_coder.get_impl()View on GitHub (pinned to 12126d8942)