{"record":{"id":"25b3542df82f10d3","repo":"alibaba/spring-cloud-alibaba","slug":"convert-error","errorCode":null,"errorMessage":"convert error: {}","messagePattern":"convert error: (.+?)","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"spring-cloud-alibaba-starters/spring-cloud-alibaba-sentinel-datasource/src/main/java/com/alibaba/cloud/sentinel/datasource/converter/SentinelConverter.java","lineNumber":105,"sourceCode":"\t\t\tfor (Object obj : sourceArray) {\n\t\t\t\ttry {\n\t\t\t\t\tString item = objectMapper.writeValueAsString(obj);\n\t\t\t\t\tOptional.ofNullable(convertRule(item))\n\t\t\t\t\t\t\t.ifPresent(convertRule -> ruleCollection.add(convertRule));\n\t\t\t\t}\n\t\t\t\tcatch (JacksonException e) {\n\t\t\t\t\tlog.error(\"sentinel rule convert error: \" + e.getMessage(), e);\n\t\t\t\t\tthrow new IllegalArgumentException(\n\t\t\t\t\t\t\t\"sentinel rule convert error: \" + e.getMessage(), e);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tcatch (Exception e) {\n\t\t\tif (e instanceof RuntimeException runtimeException) {\n\t\t\t\tthrow runtimeException;\n\t\t\t}\n\t\t\telse {\n\t\t\t\tthrow new RuntimeException(\"convert error: \" + e.getMessage(), e);\n\t\t\t}\n\t\t}\n\t\treturn ruleCollection;\n\t}\n\n\tprivate Object convertRule(String ruleStr) {\n\t\treturn objectMapper.readValue(ruleStr, ruleClass);\n\t}\n\n}\n","sourceCodeStart":87,"sourceCodeEnd":116,"githubUrl":"https://github.com/alibaba/spring-cloud-alibaba/blob/115d5901102009492e05d5ec18c3f79cad4077d0/spring-cloud-alibaba-starters/spring-cloud-alibaba-sentinel-datasource/src/main/java/com/alibaba/cloud/sentinel/datasource/converter/SentinelConverter.java#L87-L116","documentation":"Thrown by SentinelConverter.convert in the outer catch block when a non-RuntimeException occurs during the overall JSON parsing of the rule source string. If the initial objectMapper.readValue(source, List<HashMap>) call fails with a checked exception (not a JacksonException from the inner loop, and not a RuntimeException), it is wrapped in a RuntimeException. If the exception IS a RuntimeException (including the IllegalArgumentException from the inner loop), it is re-thrown as-is via the instanceof branch.","triggerScenarios":"The Sentinel rule source string is malformed at the top level — not a valid JSON array, truncated JSON, or completely non-JSON content. The ObjectMapper fails during the initial readValue call with a checked IOException or JacksonException that is not caught by the inner loop's JacksonException handler (because the failure occurs before entering the loop). For example, the source is '{not valid json' or a single JSON object instead of a JSON array.","commonSituations":"1) Rule data in the datasource is not a JSON array (e.g., a single JSON object instead of an array). 2) Rule data is corrupted, truncated, or contains encoding issues. 3) An empty-but-not-blank source that passes the StringUtils.isEmpty check but is not valid JSON (e.g., source is whitespace that somehow passes). 4) XML datasource configured but converter expects JSON.","solutions":["Validate that the rule source is a well-formed JSON array: [{...}, {...}] — a top-level JSON object or malformed JSON triggers this error.","Use a JSON validator on the rule data in your datasource (Nacos config, file, etc.) to identify syntax errors.","Ensure the data-type and rule-class configuration matches the actual data format in the datasource.","Check for encoding issues (BOM, mixed encoding) if the JSON appears correct but parsing still fails."],"exampleFix":"# before (broken — single object, not an array)\n{\"resource\": \"hello\", \"grade\": 1, \"count\": 5}\n\n# after (fixed — proper JSON array)\n[{\"resource\": \"hello\", \"grade\": 1, \"count\": 5}]","handlingStrategy":"try-catch","validationCode":"// Validate the rule source is a JSON array before the converter runs\nimport com.fasterxml.jackson.databind.ObjectMapper;\n\nObjectMapper mapper = new ObjectMapper();\ntry {\n    JsonNode node = mapper.readTree(source);\n    if (!node.isArray()) {\n        throw new IllegalArgumentException(\n            \"Sentinel rule source must be a JSON array, got: \" + node.getNodeType());\n    }\n} catch (Exception e) {\n    throw new IllegalArgumentException(\n        \"Sentinel rule source is not valid JSON: \" + e.getMessage(), e);\n}","typeGuard":null,"tryCatchPattern":"try {\n    Collection<Object> rules = converter.convert(source);\n} catch (RuntimeException e) {\n    if (e.getMessage() != null && e.getMessage().startsWith(\"convert error:\")) {\n        log.error(\"Sentinel rule source parsing failed — source may not be valid JSON array: {}\",\n            e.getMessage());\n        // Log the source for debugging, then decide whether to fail or use fallback rules\n    }\n    throw e;\n}","preventionTips":["Ensure Sentinel rule data is always a JSON array at the top level, even for a single rule.","Use a JSON schema validator on rule data before publishing to the datasource.","Add integration tests that load rules from the actual datasource to catch format issues before deployment.","Monitor datasource content for corruption (e.g., partial writes, encoding changes)."],"tags":["sentinel","converter","jackson","json","rule-parsing","deserialization"],"backgroundTag":null,"analyzedSha":"115d5901102009492e05d5ec18c3f79cad4077d0","analyzedAt":"2026-08-14T04:47:13.900Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}