{"record":{"id":"9275ca5aa7ecea8c","repo":"apache/beam","slug":"unable-to-infer-configuration-row-from-configuration-proto","errorCode":null,"errorMessage":"Unable to infer configuration row from configuration proto and schema.","messagePattern":"Unable to infer configuration row from configuration proto and schema\\.","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"sdks/java/extensions/schemaio-expansion-service/src/main/java/org/apache/beam/sdk/extensions/schemaio/expansion/ExternalSchemaIOTransformRegistrar.java","lineNumber":121,"sourceCode":"      return null;\n    }\n\n    try {\n      SchemaApi.Schema protoSchema = SchemaApi.Schema.parseFrom(schemaBytes);\n      return SchemaTranslation.schemaFromProto(protoSchema);\n    } catch (InvalidProtocolBufferException e) {\n      throw new RuntimeException(\"Unable to infer data schema from configuration proto.\", e);\n    }\n  }\n\n  private static Row translateRow(byte[] rowBytes, Schema configSchema) {\n    RowCoder rowCoder = RowCoder.of(configSchema);\n    InputStream stream = new ByteArrayInputStream(rowBytes);\n\n    try {\n      return rowCoder.decode(stream);\n    } catch (IOException e) {\n      throw new RuntimeException(\n          \"Unable to infer configuration row from configuration proto and schema.\", e);\n    }\n  }\n\n  @VisibleForTesting\n  static class ReaderBuilder\n      implements ExternalTransformBuilder<Configuration, PBegin, PCollection<Row>> {\n    SchemaIOProvider schemaIOProvider;\n\n    ReaderBuilder(SchemaIOProvider schemaIOProvider) {\n      this.schemaIOProvider = schemaIOProvider;\n    }\n\n    @Override\n    public PTransform<PBegin, PCollection<Row>> buildExternal(Configuration configuration) {\n      return schemaIOProvider\n          .from(\n              configuration.location,","sourceCodeStart":103,"sourceCodeEnd":139,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/extensions/schemaio-expansion-service/src/main/java/org/apache/beam/sdk/extensions/schemaio/expansion/ExternalSchemaIOTransformRegistrar.java#L103-L139","documentation":"ExternalSchemaIOTransformRegistrar.translateRow decodes the configuration bytes from the transform proto using a RowCoder built from the declared config schema. If the bytes do not match the schema (decode fails with IOException), it wraps the failure in this RuntimeException. It indicates the serialized configuration payload and the schema are inconsistent.","triggerScenarios":"Calling ExternalSchemaIOTransformRegistrar.translateRow with config bytes from the expansion request proto that do not conform to configSchema; schema evolved on one side (producer wrote rows with an older/newer schema) while the registrar decodes with the current schema; corrupted or truncated rowBytes.","commonSituations":"A pipeline was built with an older Beam SDK and submitted against a newer expansion service (or vice versa) so the config schema changed between serialize and deserialize; hand-crafted cross-language transforms passing malformed config protos; staging old jars with the pipeline.","solutions":["Ensure the SDK and expansion service versions match so the config schema used to encode equals the one used to decode.","Re-generate the transform payload with the current SDK (rebuild/re-submit the pipeline) instead of reusing cached expansion responses.","Inspect the nested IOException (getCause) to find the exact field/type mismatch and fix the config payload accordingly.","If constructing the proto manually, verify every schema field is set with the correct type before calling translateRow."],"exampleFix":"// before\nExpansionRequest request = loadCachedRequest(); // built with old schema\nRow row = registrar.translateRow(request.getConfigSchema(), request.getConfigRow().toByteArray());\n// after\nExpansionRequest request = fetchFreshRequestFromExpansionService(); // schema in sync with runtime\nRow row = registrar.translateRow(request.getConfigSchema(), request.getConfigRow().toByteArray());","handlingStrategy":"try-catch","validationCode":"// Before decoding, check schema/byte consistency\nif (rowBytes == null || rowBytes.length == 0) throw new IllegalArgumentException(\"empty config row bytes\");\nRowCoder.of(configSchema).verifyDeterministic(); // also validates schema is well-formed","typeGuard":null,"tryCatchPattern":"try { return rowCoder.decode(new ByteArrayInputStream(rowBytes)); }\ncatch (IOException e) { LOG.error(\"config row does not match schema {}\", configSchema, e); throw new RuntimeException(\"...\", e); }","preventionTips":["Keep SDK and expansion service versions identical","Regenerate expansion requests instead of caching them across upgrades","Log configSchema and bytes on failure for diagnosis"],"tags":["java","beam","schemaio","row-decoding","schema-mismatch"],"backgroundTag":"schema-validation-failed","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}