apache/beam · error · RuntimeException
Unexpected IOException:
Error message
Unexpected IOException:
What it means
In SingletonViewFn2's constructor, if a default value was supplied for a singleton view, Beam eagerly encodes it with the value coder via CoderUtils.encodeToByteArray. Encoding should never fail for a well-formed coder, so an IOException there indicates a broken/misconfigured coder and is rethrown as a RuntimeException with message 'Unexpected IOException: '. This is an internal-invariant failure, not a user-data problem.
Source
Thrown at sdks/java/core/src/main/java/org/apache/beam/sdk/values/PCollectionViews.java:497
private transient @Nullable T defaultValue;
private @Nullable Coder<T> valueCoder;
private boolean hasDefault;
private TypeDescriptorSupplier<T> typeDescriptorSupplier;
private SingletonViewFn2(
boolean hasDefault,
T defaultValue,
Coder<T> valueCoder,
TypeDescriptorSupplier<T> typeDescriptorSupplier) {
this.hasDefault = hasDefault;
this.defaultValue = defaultValue;
this.valueCoder = valueCoder;
this.typeDescriptorSupplier = typeDescriptorSupplier;
if (hasDefault) {
try {
this.encodedDefaultValue = CoderUtils.encodeToByteArray(valueCoder, defaultValue);
} catch (IOException e) {
throw new RuntimeException("Unexpected IOException: ", e);
}
}
}
/** Returns if a default value was specified. */
@Internal
public boolean hasDefault() {
return hasDefault;
}
/**
* Returns the default value that was specified.
*
* <p>For internal use only.
*
* @throws NoSuchElementException if no default was specified.
*/
@OverrideView on GitHub (pinned to 12126d8942)
Solutions
- Inspect the cause attached to the RuntimeException — fix the underlying custom Coder's encodeToByteArray/encode method that throws IOException.
- Verify the coder passed to withDefaultValue / the view matches the default value's actual type.
- Test the coder in isolation (CoderUtils.encodeToByteArray(coder, defaultValue)) in a unit test before running the pipeline.
- Upgrade/align Beam SDK version if the failure came from a known coder bug.
Example fix
// before (custom coder throwing)
class BuggyCoder implements Coder<MyType> { public void encode(MyType v, OutputStream out) throws IOException { throw new IOException("nyi"); } }
// after — implement encoding properly or use a registry coder
Coder<MyType> coder = SerializableCoder.of(MyType.class); Defensive patterns
Strategy: try-catch
Validate before calling
try {
CoderUtils.encodeToByteArray(valueCoder, defaultValue);
} catch (IOException e) {
throw new IllegalStateException("Coder cannot encode default value", e);
} Try / catch
try {
PCollectionView<T> view = pc.apply(View.asSingleton().withDefaultValue(d));
} catch (RuntimeException e) {
if (e.getCause() instanceof IOException) { /* fix/replace coder */ }
throw e;
} Prevention
- Prefer built-in coders (SerializableCoder, AvroCoder) over hand-rolled ones for view defaults.
- Round-trip test every custom coder before use in pipelines.
- Keep coder and value type declarations in sync during refactors.
When it happens
Trigger: Constructing a SingletonViewFn2 (e.g. via View.asSingleton().withDefaultValue(...) materialization) with a value coder whose encode throws IOException — typically a coder backed by a stream/registry failure, a closed stream, or a custom coder with a faulty encodeClosed implementation.
Common situations: Custom Coder implementations that declare checked IO but are buggy; coders for types with externalized state; using a coder incompatible with the actual default value type after a refactor or Beam version upgrade.
Related errors
- Failure to register coder
- cannot encode a null Integer
- cannot encode a null Long
- cannot encode a null Short
- cannot encode a null BitSet
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/302ea45c2896b363.
Report an issue: GitHub.