apache/flink · error · InvalidProgramException

Field expression must be equal to '*' or '_' for atomic type

Error message

Field expression must be equal to '*' or '_' for atomic types.

What it means

Thrown by Keys.ExpressionKeys.isSortKey(String, TypeInformation) when the type is not composite and the expression is not the select-all wildcard. Atomic types (String, Integer, etc.) have no addressable sub-fields, so the only valid sort expression is '*' (Java) or '_' (Scala). Any named-field expression on an atomic type is meaningless.

Source

Thrown at flink-core/src/main/java/org/apache/flink/api/common/operators/Keys.java:472

                throw new IndexOutOfBoundsException("Tuple position is out of range: " + fieldPos);
            }

            TypeInformation<?> sortKeyType = ((CompositeType<?>) type).getTypeAt(fieldPos);
            return sortKeyType.isSortKeyType();
        }

        public static boolean isSortKey(String fieldExpr, TypeInformation<?> type) {

            TypeInformation<?> sortKeyType;

            fieldExpr = fieldExpr.trim();
            if (SELECT_ALL_CHAR.equals(fieldExpr) || SELECT_ALL_CHAR_SCALA.equals(fieldExpr)) {
                sortKeyType = type;
            } else {
                if (type instanceof CompositeType) {
                    sortKeyType = ((CompositeType<?>) type).getTypeAt(fieldExpr);
                } else {
                    throw new InvalidProgramException(
                            "Field expression must be equal to '"
                                    + SELECT_ALL_CHAR
                                    + "' or '"
                                    + SELECT_ALL_CHAR_SCALA
                                    + "' for atomic types.");
                }
            }

            return sortKeyType.isSortKeyType();
        }
    }

    // --------------------------------------------------------------------------------------------

    // --------------------------------------------------------------------------------------------
    //  Utilities
    // --------------------------------------------------------------------------------------------

View on GitHub (pinned to 2f3c205e92)

Solutions

  1. Use isSortKey("*", type) or isSortKey("_", type) for atomic types.
  2. If a sub-field was intended, first convert the stream to a composite type.
  3. Branch on type instanceof CompositeType to choose expression vs wildcard.

Example fix

// before
Keys.ExpressionKeys.isSortKey("value", BasicTypeInfo.STRING_TYPE_INFO);

// after
Keys.ExpressionKeys.isSortKey("*", BasicTypeInfo.STRING_TYPE_INFO);
Defensive patterns

Strategy: type-guard

Validate before calling

if (!(type instanceof CompositeType)
        && !("*".equals(fieldExpr.trim()) || "_".equals(fieldExpr.trim()))) {
    throw new IllegalArgumentException(
        "Atomic type requires '*' or '_' as sort expression.");
}

Type guard

static boolean isValidSortExprForAtomic(String expr) {
    String t = expr.trim();
    return "*".equals(t) || "_".equals(t);
}

Prevention

When it happens

Trigger: Calling isSortKey("myField", stringTypeInfo) where the type is a String or primitive wrapper. Higher-level sort APIs that call this with a user-provided field name on a non-composite stream.

Common situations: Reusing a field-name string meant for a POJO on a stream that turned out to be a primitive. Forgetting that scalar streams require wildcard expressions.

Related errors


AI-assisted analysis of apache/flink@2f3c205e92 (2026-08-14). Data as JSON: /api/errors/25619e2bf4cbe570. Report an issue: GitHub.