apache / apache/beam

[Bug]: Row.toString throws for an ITERABLE field that is not backed by a List

Open Beginner friendly
#39,749 0 comments 0 reactions 0 assignees View on GitHub
java P3
Dominant language
Java
Stars
8.7k
Forks
4.7k
Avg merge
1d 20h
Merged PRs (30d)
196

Description

### What happened?

`Row#toString` throws for an `ITERABLE` field whose value is a plain `Iterable`:

```java
Schema schema =
Schema.builder().addStringField("k").addIterableField("vals", FieldType.STRING).build();
Iterable bare = () -> Arrays.asList("p", "q").iterator();
Row.withSchema(schema).attachValues("k1", bare).toString();
```

```
java.lang.IllegalArgumentException: value type is 'class ...' for field type 'ITERABLE'
at org.apache.beam.sdk.schemas.SchemaUtils.toPrettyFieldValueString(SchemaUtils.java:273)
```

`toPrettyFieldValueString` requires a `List` before iterating:

```java
if (!(value instanceof List)) {
throw new IllegalArgumentException(...);
}
```

An `ITERABLE` field declares an `Iterable`, so the guard is stricter than the type it is guarding. The branch below it only iterates and counts — both available from an `Iterable` once materialised.

`Row#toString` is `SchemaUtils.toPrettyString(this)`, so one unusual field takes out logging and debugger output for **every** field beside it, which is a poor trade for a stricter check in a renderer.

### Note on where the fix belongs

There is a reasonable position that a materialised `Row` should always hold a `List` for `ARRAY`/`ITERABLE`, and that a non-`List` arriving here means a producer is at fault. That may well be true and worth fixing separately — but the reproducer above uses only `Schema.builder`, `Row.withSchema(...).attachValues(...)` and `toString()`, so a value that is merely `Iterable` does reach the renderer through the public API, and a `toString()` that throws is hard to defend regardless of who produced the value.

### Issue Priority

Priority: 3 (minor)

### Issue Components

- [x] Component: Java SDK

Contributor guide

Open the contributing guide

Research direction

Start in SchemaUtils.java at toPrettyFieldValueString and trace the call from Row#toString through SchemaUtils.toPrettyString. Run the reproducer from the issue and add regression coverage for an ITERABLE backed by a plain Iterable; done means Row#toString completes without throwing for that value.

Written by the indexing model from the issue text.

Assessment

Tech stack
java
Domain
backend
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
76/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.