apache/beam · error · Error

SqlTransform can only be applied to schema'd transforms. Ple

Error message

SqlTransform can only be applied to schema'd transforms. Please ensure the input PCollection(s) have a RowCoder, or pass a prototypical element in as the second argument of SqlTransform so that one can be inferred.

What it means

SqlTransform requires its input PCollections to carry a schema, represented in the TypeScript SDK by a RowCoder. Before expanding the SQL transform, the SDK checks each input's coder; if it is not a RowCoder (e.g. plain JSON objects or primitives without an explicit schema), the SQL engine cannot map elements to columns, so it throws. Supplying a prototypical element lets the SDK infer a schema and attach a RowCoder.

Source

Thrown at sdks/typescript/src/apache_beam/transforms/sql.ts:59

 *    ));
 */
export function sqlTransform<
  InputT extends PCollection<any> | { [key: string]: PCollection<any> },
>(
  query: string,
  inputTypes = null,
): transform.AsyncPTransform<InputT, PCollection<any>> {
  // TOOD: (API) (Typescript): How to infer input_types, or at least make it optional.
  async function expandInternal(input: InputT): Promise<PCollection<any>> {
    function withCoder<T>(pcoll: PCollection<T>, type): PCollection<T> {
      if (type) {
        if (
          !(
            pcoll.pipeline.context.getPCollectionCoder(pcoll) instanceof
            row_coder.RowCoder
          )
        ) {
          throw new Error(
            "SqlTransform can only be applied to schema'd transforms. " +
              "Please ensure the input PCollection(s) have a RowCoder, " +
              "or pass a prototypical element in as the second argument " +
              "of SqlTransform so that one can be inferred.",
          );
        }
        return pcoll;
      }
      return pcoll.apply(internal.withRowCoder(type));
    }

    if (input instanceof PCollection) {
      input = withCoder(input, inputTypes) as InputT;
    } else {
      input = Object.fromEntries(
        Object.keys(input).map((tag) => [
          tag,
          withCoder(

View on GitHub (pinned to 12126d8942)

Solutions

  1. Pass a prototypical element as the second argument of SqlTransform so a RowCoder can be inferred.
  2. Ensure inputs are instances of typed classes so the SDK can infer a schema (RowCoder).
  3. Replace the raw coder with a RowCoder via withCoder on the input PCollection.
  4. Re-check the input type: SQL needs schema'd elements, not untyped JSON.

Example fix

// before
pcoll.apply(SqlTransform.query('SELECT f1 FROM PCOLLECTION'));

// after: provide a prototype so a RowCoder is inferred
pcoll.apply(SqlTransform.query('SELECT f1 FROM PCOLLECTION', new MyRow('', 0)));
Defensive patterns

Strategy: validation

Validate before calling

// before applying SqlTransform, ensure inputs carry a RowCoder schema
if (!(pcoll.pipeline.context.getPCollectionCoder(pcoll) instanceof row_coder.RowCoder)) {
  // pass a prototype: SqlTransform.query(sql, new MyRow('', 0))
}

Prevention

When it happens

Trigger: Applying SqlTransform to a PCollection of plain objects/primitives with no inferred schema, and not passing the prototype (second) argument to SqlTransform.

Common situations: Running SQL over PCollection<any> of parsed JSON where the SDK cannot infer a schema; passing class instances without schema annotations; using primitives like strings as SQL input.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/9313501c1b82801f. Report an issue: GitHub.