apache/seatunnel · error · SeaTunnelRuntimeException
COMMON-02
COMMON-02
Error message
<identifier> JSON convert/parse '<payload>' operation failed.
What it means
TypesenseRowSerializer.serializeRow converts a SeaTunnelRow into a JSON document string for Typesense indexing using Jackson's ObjectMapper. When writeValueAsString throws a JsonProcessingException (e.g. an unserializable value, non-numeric NaN, or a type Jackson cannot represent), the connector rethrows it as CommonError.jsonOperationError with the offending document payload. This indicates the row's fields cannot be converted to a valid Typesense JSON document.
Source
Thrown at seatunnel-connectors-v2/connector-typesense/src/main/java/org/apache/seatunnel/connectors/seatunnel/typesense/serialize/sink/TypesenseRowSerializer.java:65
this.keyExtractor =
KeyExtractor.createKeyExtractor(
seaTunnelRowType,
collectionInfo.getPrimaryKeys(),
collectionInfo.getKeyDelimiter());
}
@Override
public String serializeRow(SeaTunnelRow row) {
String key = keyExtractor.apply(row);
Map<String, Object> document = toDocumentMap(row, seaTunnelRowType);
if (StringUtils.isNotBlank(key)) {
document.put("id", key);
}
String documentStr;
try {
documentStr = objectMapper.writeValueAsString(document);
} catch (JsonProcessingException e) {
throw CommonError.jsonOperationError("Typesense", "document:" + document.toString(), e);
}
return documentStr;
}
@Override
public String serializeRowForDelete(SeaTunnelRow row) {
String key = keyExtractor.apply(row);
Map<String, Object> document = toDocumentMap(row, seaTunnelRowType);
String id = document.get("id").toString();
if (StringUtils.isNotBlank(key)) {
id = key;
}
return id;
}
private Map<String, Object> toDocumentMap(SeaTunnelRow row, SeaTunnelRowType rowType) {
String[] fieldNames = rowType.getFieldNames();
Map<String, Object> doc = new HashMap<>(fieldNames.length);View on GitHub (pinned to cf67b549a7)
Solutions
- Inspect the payload shown in the error message ('document:...') to find the field holding the non-serializable value and fix the upstream data or transform (e.g. replace NaN/Infinity with null).
- Ensure the SeaTunnel catalog type of every column is JSON-serializable (basic types, arrays, maps, rows); cast or transform unsupported column types before the Typesense sink.
- If the ObjectMapper needs feature flags (e.g. serialize NaN as strings), configure serialization features on the serializer's objectMapper before running the job.
- Enable debug logging and run the job in local mode to capture the full JsonProcessingException cause chained in this error.
Example fix
// before: row contains NaN double from source row.setField(2, Double.NaN); // Typesense sink -> jsonOperationError // after: sanitize before sink row.setField(2, Double.isNaN(value) || Double.isInfinite(value) ? null : value);
Defensive patterns
Strategy: try-catch
Validate before calling
// before calling serializeRow, sanity-check serializable fields
for (int i = 0; i < row.getArity(); i++) {
Object v = row.getField(i);
if (v instanceof Double d && (d.isNaN() || d.isInfinite())) {
throw new IllegalArgumentException("field " + i + " not JSON-serializable: " + v);
}
} Type guard
static boolean isJsonSerializable(Object v) {
return v == null || v instanceof String || v instanceof Number
|| v instanceof Boolean || v instanceof Map || v instanceof Iterable || v.getClass().isArray();
} Try / catch
try {
String doc = serializer.serializeRow(row);
} catch (org.apache.seatunnel.api.common.SeaTunnelRuntimeException e) {
if (e.getSeaTunnelErrorCode() == CommonError.code) {
LOG.error("Typesense serialize failed for payload: {}", e.getFormattedMessage(), e);
// skip, dead-letter, or fix row before retry
} else { throw e; }
} Prevention
- Sanitize NaN/Infinity and other non-JSON values in transforms before the sink
- Keep sink columns limited to JSON-native SeaTunnel types (string, int, long, double, boolean, array, map, row)
- Run a small batch in local mode first to catch serialization issues with full stack traces
When it happens
Trigger: Calling serializeRow on a SeaTunnelRow whose map/document contains values Jackson cannot serialize (e.g. Infinity/NaN doubles with default ObjectMapper settings, raw Java objects with no bean properties, or cyclic structures). Any SeaTunnelRow -> Typesense document conversion failure inside writeValueAsString triggers this.
Common situations: Source data contains NaN or Infinity floating point values loaded from databases or files; a custom SeaTunnelRow field type (e.g. a POJO or byte[]) is passed through without being mapped to a JSON-compatible SeaTunnelType; schema fields changed upstream so document values no longer match expected types.
Understand the failure class
Background: json.Marshal / "failed to marshal" errors in Go: why "unsupported type" happens and how to fix it — this error's family across 22 libraries.
Related errors
- Object to json exception!
- Object json deserialization exception.
- Failed to convert row to JSON
- JSON_OPERATION_FAILED
- COMMON_UNSUPPORTED_DATA_TYPE
AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10).
Data as JSON: /api/errors/f894d40ba924813f.
Report an issue: GitHub.