apache/beam · error · IllegalArgumentException
TupleTag ${tag} corresponds to a non-singleton result
Error message
TupleTag ${tag} corresponds to a non-singleton result What it means
getOnly() asserts the requested tag maps to exactly one value for the key. If more than one element exists in the iterable for that tag, the result is non-singleton and the method refuses to silently pick one.
Source
Thrown at sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/join/CoGbkResult.java:409
private @Nullable <V> V innerGetOnly(
TupleTag<V> tag, @Nullable V defaultValue, boolean useDefault) {
int index = schema.getIndex(tag);
if (index < 0) {
throw new IllegalArgumentException("TupleTag " + tag + " is not in the schema");
}
@SuppressWarnings("unchecked")
Iterator<V> unions = (Iterator<V>) valueMap.get(index).iterator();
if (!unions.hasNext()) {
if (useDefault) {
return defaultValue;
} else {
throw new IllegalArgumentException(
"TupleTag " + tag + " corresponds to an empty result, and no default was provided");
}
}
V value = unions.next();
if (unions.hasNext()) {
throw new IllegalArgumentException(
"TupleTag " + tag + " corresponds to a non-singleton result");
}
return value;
}
/**
* A re-iterable that notifies an observer at every advance, and upon finishing, but only once
* across all copies.
*
* @param <T> The value type of the underlying iterable.
*/
private static class ObservingReiterator<T> implements Reiterator<T> {
public interface Observer<T> {
/**
* Called exactly once, across all copies before advancing this iterator.
*
* <p>The iterator rather than the element is given so that the callee can perform a copy ifView on GitHub (pinned to 12126d8942)
Solutions
- Use get(tag) to obtain an Iterable and iterate all values
- Ensure the PCollection for that tag is deduplicated per key (e.g. Distinct or combine) before joining
- Use getAll(tag) when multiple values are legitimate
Example fix
// before
V v = result.getOnly(tag); // throws if multiple
// after
for (V v : result.getAll(tag)) { /* handle each */ } Defensive patterns
Strategy: validation
Validate before calling
if (result.getAll(tag).iterator().hasNext() && result.getAll(tag).spliterator().getExactSizeIfKnown() != 1) { /* handle multi-value */ } Try / catch
try { return result.getOnly(tag); } catch (IllegalArgumentException e) { /* fall back to iterable handling */ } Prevention
- Use get()/getAll() unless you guarantee singleton cardinality
- Deduplicate inputs per key before joining
- Combine values per key before CoGroupByKey
When it happens
Trigger: Calling getOnly(tag) on a key where the corresponding PCollection produced multiple records for that key in the CoGroupByKey output.
Common situations: Using getOnly() on many-to-many join results; one side of the join emits multiple values per key (e.g. repeated events per user id).
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
- TupleTag ${tag} corresponds to an empty result, and no defau
- Attempting to call and() on a CoGbkResult apparently not cre
- Unknown context parameter: ${param.parDoParamName}
- Unsupported window mapping fn: ${sideInput.windowMappingFn.u
- Unimplemented access pattern: ${accessPattern}
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/6f3d6e493f3512c5.
Report an issue: GitHub.