apache/iceberg · error · ValidationException

String.format("Invalid term: , expected either a bound…

Error message

String.format("Invalid term: %s, expected either a bound reference or transform", term)

What it means

Type check in SortOrder.Builder.toTransform: the term passed to sortField is neither a BoundReference (a plain column) nor a BoundTransform (a transform applied to a column), so it cannot be converted into a sort field. The %s is the offending term; common causes are passing an UnboundTerm or an arbitrary Term subtype that was never bound to a schema.

Solutions

  1. Bind the term against the table schema before adding it as a sort field
  2. Use Expressions.col(...).plus metadata binding via the table's resolver to obtain a BoundReference/BoundTransform
  3. Reject unsupported term types at the API boundary with a clearer message
Defensive patterns

Strategy: type-guard

When it happens

Trigger: Thrown at api/src/main/java/org/apache/iceberg/SortOrder.java:292 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12). Data as JSON: /api/errors/888f260a6595ad18. Report an issue: GitHub.

Appendix: source

Thrown at api/src/main/java/org/apache/iceberg/SortOrder.java:292

        return SortOrder.unsorted();
      }

      if (orderId != null && orderId == 0) {
        throw new IllegalArgumentException("Sort order ID 0 is reserved for unsorted order");
      }

      // default ID to 1 as 0 is reserved for unsorted order
      int actualOrderId = orderId != null ? orderId : 1;
      return new SortOrder(schema, actualOrderId, fields);
    }

    private Transform<?, ?> toTransform(BoundTerm<?> term) {
      if (term instanceof BoundReference) {
        return Transforms.identity(term.type());
      } else if (term instanceof BoundTransform) {
        return ((BoundTransform<?, ?>) term).transform();
      } else {
        throw new ValidationException(
            "Invalid term: %s, expected either a bound reference or transform", term);
      }
    }
  }

  public static void checkCompatibility(SortOrder sortOrder, Schema schema) {
    for (SortField field : sortOrder.fields) {
      Type sourceType = schema.findType(field.sourceId());
      ValidationException.check(
          sourceType != null, "Cannot find source column for sort field: %s", field);
      ValidationException.check(
          sourceType.isPrimitiveType(),
          "Cannot sort by non-primitive source field: %s",
          sourceType);
      ValidationException.check(
          field.transform().canTransform(sourceType),
          "Invalid source type %s for transform: %s",
          sourceType,

View on GitHub (pinned to 86d9c8fc54)