{"record":{"id":"0863bc10ae4900c7","repo":"apache/beam","slug":"error-decoding-payload","errorCode":null,"errorMessage":"Error decoding payload","messagePattern":"Error decoding payload","errorType":"exception","errorClass":"java.lang.RuntimeException","httpStatus":null,"severity":"error","filePath":"sdks/java/expansion-service/src/main/java/org/apache/beam/sdk/expansion/service/ExpansionService.java","lineNumber":428,"sourceCode":"                (field) -> {\n                  Preconditions.checkNotNull(field.getName());\n                  if (field.getName().contains(\"_\")) {\n                    @Nullable String newName = camelCaseConverter.convert(field.getName());\n                    assert newName != null\n                        : \"@AssumeAssertion(nullness): converter type is imprecise; it is\"\n                            + \" nullness-preserving\";\n                    return field.withName(newName);\n                  } else {\n                    return field;\n                  }\n                })\n            .collect(Schema.toSchema());\n\n    Row configRow;\n    try {\n      configRow = RowCoder.of(payloadSchema).decode(payload.newInput());\n    } catch (IOException e) {\n      throw new RuntimeException(\"Error decoding payload\", e);\n    }\n    return configRow;\n  }\n\n  /**\n   * Attempt to create an instance of {@link ConfigT} from an {@link ExternalConfigurationPayload}.\n   * If a schema is registered for {@link ConfigT} this method will attempt to ise it. Throws an\n   * {@link IllegalArgumentException} if the schema in {@code payload} is not {@link\n   * Schema#assignableTo(Schema) assignable to} the registered schema.\n   *\n   * <p>If no Schema is registered, {@link ConfigT} must have a zero-argument constructor and\n   * setters corresponding to each field in the row encoded by {@code payload}. Note {@link ConfigT}\n   * may have additional setters not represented in the {@code payload} schema.\n   *\n   * <p>Exposed for testing only. No backwards compatibility guarantees.\n   */\n  @VisibleForTesting\n  public static <ConfigT> ConfigT payloadToConfig(","sourceCodeStart":410,"sourceCodeEnd":446,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/expansion-service/src/main/java/org/apache/beam/sdk/expansion/service/ExpansionService.java#L410-L446","documentation":"ExpansionService.decodeConfigObjectRow() decodes the ExternalConfigurationPayload's serialized bytes into a Row using a RowCoder built from the payload's schema; an IOException during decode is wrapped in this RuntimeException. It means the payload bytes do not match the payload schema.","triggerScenarios":"Calling decodeConfigObjectRow (directly or via payloadRow/configRow) when RowCoder.of(payloadSchema).decode(payload.newInput()) throws IOException - typically byte/schema mismatch or truncated payload.","commonSituations":"Sender encodes config with a different schema version than the one advertised in the payload proto; corrupted payload in transit; hand-crafted FunctionSpec payloads in tests.","solutions":["Verify the payload bytes were encoded with the same schema embedded in the ExternalConfigurationPayload","Regenerate the payload from the client SDK instead of hand-rolling protobuf bytes","Align Beam SDK versions between sender and expansion service","Log the payload schema and compare field-by-field with what the sender encodes"],"exampleFix":"// before: schema and bytes diverge after adding a field client-side\nRow encoded with old schema but new schema declared in payload\n// after: rebuild payload with schema-carrying helper on both sides\nExternalConfigurationPayload payload = ExternalConfigurationPayload.create(schema, bytes, null);","handlingStrategy":"validation","validationCode":"// confirm payload schema matches the bytes before decode\nSchema payloadSchema = SchemaTranslation.schemaFromProto(payload.getSchema());\nRow roundTrip = RowCoder.of(payloadSchema).decode(new ByteArrayInputStream(RowCoder.of(payloadSchema).encode(row).array()));","typeGuard":null,"tryCatchPattern":"try { row = decodeConfigObjectRow(payload, schema); } catch (RuntimeException e) { if (e.getMessage().equals(\"Error decoding payload\")) { /* re-encode payload with the advertised schema */ } throw e; }","preventionTips":["Never hand-craft payload bytes; build them with the SDK's ExternalConfigurationPayload helpers","Regenerate payloads after any schema change","Keep sender and expansion service on the same Beam version"],"tags":["java","beam","expansion-service","row-coder","decoding"],"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"}