apache/iceberg · error · UnsupportedOperationException
${getClass().getName()} does not implement length
Error message
${getClass().getName()} does not implement length What it means
FileScopedPositionDeleteWriter wraps per-file position delete writers and delegates length() to the current writer. When no per-file writer is active (or the underlying writer type cannot report length), it throws UnsupportedOperationException with the class name, signaling that length is not available from this writer abstraction.
Source
Thrown at core/src/main/java/org/apache/iceberg/deletes/FileScopedPositionDeleteWriter.java:76
@Override
public void write(PositionDelete<T> positionDelete) {
writer(positionDelete.path()).write(positionDelete);
}
private FileWriter<PositionDelete<T>, DeleteWriteResult> writer(CharSequence path) {
if (currentWriter == null) {
openCurrentWriter(path);
} else if (CharSequenceUtil.unequalPaths(currentPath, path)) {
closeCurrentWriter();
openCurrentWriter(path);
}
return currentWriter;
}
@Override
public long length() {
throw new UnsupportedOperationException(getClass().getName() + " does not implement length");
}
@Override
public DeleteWriteResult result() {
Preconditions.checkState(closed, "Cannot get result from unclosed writer");
return new DeleteWriteResult(deleteFiles, referencedDataFiles);
}
@Override
public void close() throws IOException {
if (!closed) {
closeCurrentWriter();
this.closed = true;
}
}
private void openCurrentWriter(CharSequence path) {
Preconditions.checkState(!closed, "Writer has already been closed");View on GitHub (pinned to 86d9c8fc54)
Solutions
- Do not call length() on FileScopedPositionDeleteWriter; obtain sizes from the DeleteWriteResult's deleteFiles after result()
- Use a different writer implementation that supports length() if byte-length tracking is required
- Report metrics from the wrapped current writer's result files instead of the wrapper
- Check whether the code path should be using a fan-out/clustered writer rather than a file-scoped one
Defensive patterns
Strategy: validation
Validate before calling
if (writer instanceof FileScopedPositionDeleteWriter) {
throw new IllegalArgumentException("length() not supported; read sizes from result delete files");
} Type guard
boolean supportsLength(LengthReportingWriter w) {
return !(w instanceof FileScopedPositionDeleteWriter);
} Try / catch
try {
long len = writer.length();
} catch (UnsupportedOperationException e) {
long len = writer.result().deleteFiles().stream().mapToLong(DeleteFile::fileSizeInBytes).sum();
} Prevention
- Don't call length() on file-scoped writers; use DeleteWriteResult sizes
- Pick a writer implementation whose contract matches metric needs
- Avoid generic code that assumes all writers report length
- Check the class hierarchy before relying on inherited metric APIs
When it happens
Trigger: Calling length() on a FileScopedPositionDeleteWriter - the class deliberately does not implement it; callers expecting a measurable output stream length (e.g. generic writer metrics code) hit this.
Common situations: Framework code that unconditionally polls writer length for progress reporting or file-size checks; misuse of the file-scoped writer where a rollable/measurable writer (e.g. ClusteredDataWriter-style) was expected.
Related errors
- Cannot modify
- Cannot modify ${getClass().getName()}
- Failed to close current writer
- ${getClass().getName()} does not support merge
- Unsupported delete granularity: <granularity>
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/38e32a20326b892e.
Report an issue: GitHub.