{"record":{"id":"f894d40ba924813f","repo":"apache/seatunnel","slug":"common-02-f894d4","errorCode":"COMMON-02","errorMessage":"<identifier> JSON convert/parse '<payload>' operation failed.","messagePattern":"<identifier> JSON convert/parse '<payload>' operation failed\\.","errorType":"error_code","errorClass":"SeaTunnelRuntimeException","httpStatus":null,"severity":"error","filePath":"seatunnel-connectors-v2/connector-typesense/src/main/java/org/apache/seatunnel/connectors/seatunnel/typesense/serialize/sink/TypesenseRowSerializer.java","lineNumber":65,"sourceCode":"        this.keyExtractor =\n                KeyExtractor.createKeyExtractor(\n                        seaTunnelRowType,\n                        collectionInfo.getPrimaryKeys(),\n                        collectionInfo.getKeyDelimiter());\n    }\n\n    @Override\n    public String serializeRow(SeaTunnelRow row) {\n        String key = keyExtractor.apply(row);\n        Map<String, Object> document = toDocumentMap(row, seaTunnelRowType);\n        if (StringUtils.isNotBlank(key)) {\n            document.put(\"id\", key);\n        }\n        String documentStr;\n        try {\n            documentStr = objectMapper.writeValueAsString(document);\n        } catch (JsonProcessingException e) {\n            throw CommonError.jsonOperationError(\"Typesense\", \"document:\" + document.toString(), e);\n        }\n        return documentStr;\n    }\n\n    @Override\n    public String serializeRowForDelete(SeaTunnelRow row) {\n        String key = keyExtractor.apply(row);\n        Map<String, Object> document = toDocumentMap(row, seaTunnelRowType);\n        String id = document.get(\"id\").toString();\n        if (StringUtils.isNotBlank(key)) {\n            id = key;\n        }\n        return id;\n    }\n\n    private Map<String, Object> toDocumentMap(SeaTunnelRow row, SeaTunnelRowType rowType) {\n        String[] fieldNames = rowType.getFieldNames();\n        Map<String, Object> doc = new HashMap<>(fieldNames.length);","sourceCodeStart":47,"sourceCodeEnd":83,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-connectors-v2/connector-typesense/src/main/java/org/apache/seatunnel/connectors/seatunnel/typesense/serialize/sink/TypesenseRowSerializer.java#L47-L83","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before: row contains NaN double from source\nrow.setField(2, Double.NaN); // Typesense sink -> jsonOperationError\n// after: sanitize before sink\nrow.setField(2, Double.isNaN(value) || Double.isInfinite(value) ? null : value);","handlingStrategy":"try-catch","validationCode":"// before calling serializeRow, sanity-check serializable fields\nfor (int i = 0; i < row.getArity(); i++) {\n  Object v = row.getField(i);\n  if (v instanceof Double d && (d.isNaN() || d.isInfinite())) {\n    throw new IllegalArgumentException(\"field \" + i + \" not JSON-serializable: \" + v);\n  }\n}","typeGuard":"static boolean isJsonSerializable(Object v) {\n  return v == null || v instanceof String || v instanceof Number\n      || v instanceof Boolean || v instanceof Map || v instanceof Iterable || v.getClass().isArray();\n}","tryCatchPattern":"try {\n  String doc = serializer.serializeRow(row);\n} catch (org.apache.seatunnel.api.common.SeaTunnelRuntimeException e) {\n  if (e.getSeaTunnelErrorCode() == CommonError.code) {\n    LOG.error(\"Typesense serialize failed for payload: {}\", e.getFormattedMessage(), e);\n    // skip, dead-letter, or fix row before retry\n  } else { throw e; }\n}","preventionTips":["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"],"tags":["jackson","serialization","typesense","sink"],"backgroundTag":"json-marshal-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"}