apache/dolphinscheduler · error · RuntimeException
itemsList is null
Error message
itemsList is null
What it means
WeChatSender.markdownText parses the alert content string as a JSON array of LinkedHashMap objects to build the WeChat markdown message. If the content is non-empty but does not deserialize into a non-empty list (wrong shape or unparseable JSON), it logs 'itemsList is null' and throws this RuntimeException, refusing to send a malformed WeChat alert.
Source
Thrown at dolphinscheduler-alert/dolphinscheduler-alert-plugins/dolphinscheduler-alert-wechat/src/main/java/org/apache/dolphinscheduler/plugin/alert/wechat/WeChatSender.java:117
log.info("Enterprise WeChat send [{}], param:{}, resp:{}",
url, data, resp);
return resp;
}
}
/**
* convert text to markdown style
*
* @param title the title
* @param content the content
* @return markdown text
*/
private static String markdownText(String title, String content) {
if (StringUtils.isNotEmpty(content)) {
List<LinkedHashMap> mapItemsList = JSONUtils.toList(content, LinkedHashMap.class);
if (null == mapItemsList || mapItemsList.isEmpty()) {
log.error("itemsList is null");
throw new RuntimeException("itemsList is null");
}
StringBuilder contents = new StringBuilder(100);
contents.append(String.format("`%s`%n", title));
for (LinkedHashMap mapItems : mapItemsList) {
Set<Map.Entry<String, Object>> entries = mapItems.entrySet();
for (Entry<String, Object> entry : entries) {
contents.append(WeChatAlertConstants.MARKDOWN_QUOTE);
contents.append(entry.getKey()).append(":").append(entry.getValue());
contents.append(WeChatAlertConstants.MARKDOWN_ENTER);
}
}
return contents.toString();
}
return null;
}View on GitHub (pinned to 02eac45a1b)
Solutions
- Ensure the alert content is a JSON array of objects, e.g. '[{"title":"x","content":"y"}]', matching what markdownText expects.
- Check which alert template/format generated the content and switch the alert instance or template so it emits the list-of-maps JSON.
- Validate the alert data JSON with a JSON parser before the alert fires to catch malformed payloads early.
Example fix
// before: alert data passed to WeChat plugin
"task failed with exit code 1"
// after: JSON list of maps
"[{\"title\":\"task failed\",\"content\":\"exit code 1\"}]" Defensive patterns
Strategy: validation
Validate before calling
List<LinkedHashMap> items = JSONUtils.toList(content, LinkedHashMap.class);
if (StringUtils.isEmpty(content) || items == null || items.isEmpty()) {
throw new IllegalArgumentException("WeChat alert content must be a non-empty JSON array of objects: " + content);
} Type guard
boolean isWeChatMarkdownPayload(String s) {
if (s == null || !s.trim().startsWith("[")) return false;
List<LinkedHashMap> l = JSONUtils.toList(s, LinkedHashMap.class);
return l != null && !l.isEmpty();
} Try / catch
try {
weChatSender.send(alert);
} catch (RuntimeException e) {
if ("itemsList is null".equals(e.getMessage())) {
log.error("Alert content is not a JSON list of maps; check the alert template: {}", alert.getContent());
}
} Prevention
- Keep alert content producers emitting a JSON array of objects for WeChat markdown alerts.
- Do not reuse alert data formatted for email/text plugins with the WeChat plugin.
- Unit-test the plugin with the exact content shape your alert template produces.
When it happens
Trigger: An alert reaches the WeChat plugin whose content is not a JSON array of objects — e.g. plain text alert data, an empty array '[]', or JSON that JSONUtils.toList cannot parse, while the content string itself is non-empty.
Common situations: Wiring a WeChat (markdown) alert to alert data produced for a different plugin (e.g. email/plain text formats); upstream alert payload format changed; alert content column contains text instead of the expected JSON list of maps.
Understand the failure class
Background: "failed to unmarshal" / json.Unmarshal errors: why parsing a response into a Go struct fails and how to fix it — this error's family across 23 libraries.
Related errors
AI-assisted analysis of apache/dolphinscheduler@02eac45a1b (2026-09-06).
Data as JSON: /api/errors/9ebb73dc919ded96.
Report an issue: GitHub.