{"record":{"id":"bc0bdd4799b09e83","repo":"apache/beam","slug":"encountered-a-managed-transform-that-has-an-empty-transform","errorCode":null,"errorMessage":"Encountered a Managed Transform that has an empty \"transform_identifier\": %n%s","messagePattern":"Encountered a Managed Transform that has an empty \"transform_identifier\": %n(.+?)","errorType":"exception","errorClass":"java.lang.IllegalStateException","httpStatus":null,"severity":"error","filePath":"sdks/java/core/src/main/java/org/apache/beam/sdk/util/construction/PTransformTranslation.java","lineNumber":546,"sourceCode":"                components.getEnvironmentIdFor(appliedPTransform.getResourceHints()));\n          }\n        }\n\n        if (spec.getUrn().equals(BeamUrns.getUrn(SCHEMA_TRANSFORM))) {\n          ExternalTransforms.SchemaTransformPayload payload =\n              ExternalTransforms.SchemaTransformPayload.parseFrom(spec.getPayload());\n          String identifier = payload.getIdentifier();\n          transformBuilder.putAnnotations(\n              BeamUrns.getConstant(Annotations.Enum.SCHEMATRANSFORM_URN_KEY),\n              ByteString.copyFromUtf8(identifier));\n          if (identifier.equals(MANAGED_TRANSFORM_URN)) {\n            Schema configSchema =\n                SchemaTranslation.schemaFromProto(payload.getConfigurationSchema());\n            Row configRow =\n                RowCoder.of(configSchema).decode(payload.getConfigurationRow().newInput());\n            String underlyingIdentifier = configRow.getString(\"transform_identifier\");\n            if (underlyingIdentifier == null) {\n              throw new IllegalStateException(\n                  String.format(\n                      \"Encountered a Managed Transform that has an empty \\\"transform_identifier\\\": %n%s\",\n                      configRow));\n            }\n            transformBuilder.putAnnotations(\n                BeamUrns.getConstant(Annotations.Enum.MANAGED_UNDERLYING_TRANSFORM_URN_KEY),\n                ByteString.copyFromUtf8(underlyingIdentifier));\n          }\n        }\n      }\n\n      Row configRow = null;\n      try {\n        configRow = payloadTranslator.toConfigRow(appliedPTransform.getTransform());\n      } catch (UnsupportedOperationException e) {\n        // Optional toConfigRow() has not been implemented. We can just ignore.\n      } catch (Exception e) {\n        LOG.warn(","sourceCodeStart":528,"sourceCodeEnd":564,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/core/src/main/java/org/apache/beam/sdk/util/construction/PTransformTranslation.java#L528-L564","documentation":"Beam's Managed transform wraps an underlying transform (e.g. Iceberg, KafkaIO) whose identity is stored in a schema'd config Row under the 'transform_identifier' field. During pipeline translation the decoded config Row must contain a non-null identifier so the MANAGED_UNDERLYING_TRANSFORM_URN_KEY annotation can be attached; if it is null the pipeline definition is corrupt and translation aborts with this IllegalStateException.","triggerScenarios":"Translating a pipeline whose RunnerApi payload contains a Managed transform (urn beam:transform:managed:v1) whose configuration Row lacks the 'transform_identifier' field or holds null for it — typically from a hand-built or cross-SDK-generated proto payload, or an older SDK writing a Managed payload without the identifier.","commonSituations":"Running a pipeline graph produced by a different Beam version or SDK that serializes Managed transforms differently; manually editing or post-processing a pipeline JSON/proto and dropping the config field; a runner deserializing a graph from a stale saved artifact.","solutions":["Regenerate the pipeline with the same (or newer) Beam version on both the construction and expansion side so the Managed payload includes 'transform_identifier'","Inspect the pipeline representation (e.g. --pipelineDump / proto) and verify the Managed transform's configuration Row has a non-null 'transform_identifier'","Replace the Managed transform with the direct underlying transform (e.g. KafkaIO, IcebergIO) to bypass Managed translation"],"exampleFix":"// before\nRow config = Row.withSchema(configSchema).addValues(null).build(); // no transform_identifier\n// after\nRow config = Row.withSchema(configSchema).addValues(\"beam:transform:kafka:write_v1\").addValues(otherCfg).build();","handlingStrategy":"validation","validationCode":"Row cfg = RowCoder.of(configSchema).decode(payload.getConfigurationRow().newInput());\nif (cfg.getString(\"transform_identifier\") == null) throw new IllegalArgumentException(\"Managed payload missing transform_identifier\");","typeGuard":"boolean hasIdentifier(Row row) { return row != null && row.getSchema().getFieldNames().contains(\"transform_identifier\") && row.getString(\"transform_identifier\") != null; }","tryCatchPattern":null,"preventionTips":["Keep Beam versions identical across graph construction, expansion, and runtime","Never hand-edit pipeline protos/JSON for Managed transforms","Prefer explicit underlying transforms when Managed support is uncertain"],"tags":["java","apache-beam","pipeline-construction","managed-transform"],"backgroundTag":"missing-required-config-field","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-20T03:17:13.778Z"}