{"record":{"id":"cbd7051897a05bb9","repo":"apache/seatunnel","slug":"illegal-argument-cbd705","errorCode":"ILLEGAL_ARGUMENT","errorMessage":"Illegal SeaTunnelRowType: ","messagePattern":"Illegal SeaTunnelRowType: ","errorType":"error_code","errorClass":"IotdbConnectorException","httpStatus":null,"severity":"error","filePath":"seatunnel-connectors-v2/connector-iotdb-v2/src/main/java/org/apache/seatunnel/connectors/seatunnel/iotdbv2/serialize/DefaultSeaTunnelRowDeserializer.java","lineNumber":57,"sourceCode":"public class DefaultSeaTunnelRowDeserializer implements SeaTunnelRowDeserializer {\n\n    private final SeaTunnelRowType rowType;\n\n    private final String sqlDialect;\n\n    @Override\n    public SeaTunnelRow deserialize(RowRecord rowRecord) {\n        if (SourceConstants.TABLE.equalsIgnoreCase(sqlDialect)) {\n            return convertTableRow(rowRecord);\n        }\n        return convert(rowRecord);\n    }\n\n    private SeaTunnelRow convert(RowRecord rowRecord) {\n        long timestamp = rowRecord.getTimestamp();\n        List<Field> fields = rowRecord.getFields();\n        if (fields.size() != (rowType.getTotalFields() - 1)) {\n            throw new IotdbConnectorException(\n                    CommonErrorCode.ILLEGAL_ARGUMENT, \"Illegal SeaTunnelRowType: \" + rowRecord);\n        }\n        Object[] seaTunnelFields = new Object[rowType.getTotalFields()];\n        seaTunnelFields[0] = convertTimestamp(timestamp, rowType.getFieldType(0));\n        for (int i = 1; i < rowType.getTotalFields(); i++) {\n            Field field = fields.get(i - 1);\n            if (field == null || field.getDataType() == null) {\n                seaTunnelFields[i] = null;\n                continue;\n            }\n            SeaTunnelDataType<?> seaTunnelFieldType = rowType.getFieldType(i);\n            seaTunnelFields[i] = convert(seaTunnelFieldType, field);\n        }\n        return new SeaTunnelRow(seaTunnelFields);\n    }\n\n    private SeaTunnelRow convertTableRow(RowRecord rowRecord) {\n        List<Field> fields = rowRecord.getFields();","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-connectors-v2/connector-iotdb-v2/src/main/java/org/apache/seatunnel/connectors/seatunnel/iotdbv2/serialize/DefaultSeaTunnelRowDeserializer.java#L39-L75","documentation":"DefaultSeaTunnelRowDeserializer.convert() for table-format records expects the IoTDB RowRecord field count to equal rowType.getTotalFields() - 1 (the timestamp becomes the first SeaTunnel column). A mismatch throws ILLEGAL_ARGUMENT with the offending record.","triggerScenarios":"Deserializing an IoTDB RowRecord whose field count differs from the SeaTunnelRowType total minus one, e.g., the IoTDB measurement set changed or the declared schema has wrong column count.","commonSituations":"Measurements added/removed in IoTDB after the SeaTunnel job was configured, schema mismatch between source table definition and IoTDB timeseries, or selected measurements filtered out by the query.","solutions":["Align the SeaTunnel catalog schema so totalFields == IoTDB fields + 1 (timestamp first).","Re-check the IoTDB query's selected measurements; ensure all are present in each record.","Update the job config after any IoTDB timeseries schema change."],"exampleFix":"// before\nrowType fields = [ts, temp]  // IoTDB returns 2 fields\n// after\nrowType fields = [ts, temp, humidity] // matches IoTDB's 2 fields + timestamp","handlingStrategy":"validation","validationCode":"// before deserialization\nif (iotdbRecord.getFields().size() + 1 != rowType.getTotalFields()) {\n    throw new IllegalStateException(\"Schema mismatch: IoTDB fields=\" + iotdbRecord.getFields().size()\n        + \" expected=\" + (rowType.getTotalFields() - 1));\n}","typeGuard":null,"tryCatchPattern":"try {\n    SeaTunnelRow row = deserializer.deserialize(record);\n} catch (IotdbConnectorException e) {\n    log.error(\"Record does not match declared schema: {}\", e.getMessage());\n    throw e;\n}","preventionTips":["Keep SeaTunnel schema = IoTDB measurements + leading timestamp column.","Re-sync schema whenever IoTDB timeseries change.","Query measurements explicitly, not with wildcards."],"tags":["iotdb","deserialization","schema"],"backgroundTag":"schema-validation-failed","analyzedSha":"cf67b549a7a6c35fa0beb12d83c62892427ea919","analyzedAt":"2026-09-10T21:44:55.265Z","contentChangedAt":"2026-09-10T21:44:55.265Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}