alibaba/spring-ai-alibaba · error · RuntimeException

ListOperatorNode apply failed (wraps caught exception)

Error message

ListOperatorNode apply failed (wraps caught exception)

What it means

ListOperatorNode.apply wraps its entire body in try/catch; any exception inside (the mode type guards above, Jackson parse errors, filter/transform/sort failures) is logged and rethrown as a wrapping RuntimeException. The message 'ListOperatorNode apply failed' indicates the node's processing pipeline failed; the original cause (bad JSON, wrong element type, exception in a user-supplied comparator/filter) is in getCause().

Source

Thrown at spring-boot-starters/spring-ai-alibaba-starter-builtin-nodes/src/main/java/com/alibaba/cloud/ai/graph/node/ListOperatorNode.java:125

				}
			};
			List<T> listElements = inputList.stream()
				.filter(filterChain)
				.sorted(comparatorChain)
				.limit(limitNumber != null && limitNumber > 0 ? limitNumber : Long.MAX_VALUE)
				.toList();

			Object output = switch (mode) {
				case JSON_STR -> objectMapper.writeValueAsString(listElements);
				case LIST -> listElements;
				case ARRAY -> listElements.toArray();
			};

			return Map.of(outputKey, output);
		}
		catch (Exception e) {
			log.error("ListOperatorNode apply failed, message: {}", e.getMessage());
			throw new RuntimeException(e);
		}
	}

	public static class Builder<T> {

		private Mode mode;

		private String inputKey;

		private String outputKey;

		private final List<Predicate<T>> filters;

		private final List<Comparator<T>> comparators;

		private Long limitNumber;

		private Class<T> type;

View on GitHub (pinned to f82da0b50f)

Solutions

  1. Log/inspect e.getCause() — it names the real failing step.
  2. Validate the input JSON parses to a List of the expected element type before the node runs.
  3. Ensure filters/transformers/comparators passed via the Builder are null-safe and type-safe.
  4. Specify the concrete element type via the Builder's type parameter rather than raw Object.

Example fix

// before
catch (Exception e) {
    log.error("ListOperatorNode apply failed, message: {}", e.getMessage());
    throw new RuntimeException(e);
}
// after
catch (Exception e) {
    log.error("ListOperatorNode apply failed", e);
    throw new RuntimeException("ListOperatorNode apply failed", e);
}
Defensive patterns

Strategy: try-catch

Validate before calling

String json = (String) state.value("items").orElse(null);
if (json != null) {
    JsonNode n = objectMapper.readTree(json);
    if (!n.isArray()) throw new IllegalStateException("Expected JSON array for ListOperatorNode");
}

Type guard

boolean isValidListOperatorInput(OverAllState state, String key, Mode mode) {
    return switch (mode) {
        case JSON_STR -> state.value(key).map(v -> v instanceof String).orElse(false);
        case LIST -> state.value(key).map(v -> v instanceof List).orElse(false);
        case ARRAY -> state.value(key).map(v -> v != null && v.getClass().isArray()).orElse(false);
    };
}

Try / catch

try {
    out = listOperator.apply(state);
} catch (RuntimeException e) {
    log.error("ListOperator failed, root cause: {}", e.getCause(), e);
    throw e.getCause() instanceof RuntimeException re ? re : e;
}

Prevention

When it happens

Trigger: Any failure within apply: malformed JSON string in JSON_STR mode, elements not assignable to T when parsing/deserializing, exceptions thrown by configured filterChain/transformers/sort comparators, or null input for any mode.

Common situations: Jackson failing to parse element type T (missing type info for generic elements); user comparator throwing on heterogeneous elements; JSON string with wrong structure (object instead of array).

Understand the failure class

Background: JSON parse error: "Unexpected token" / "not valid JSON" / "failed to parse" — what JSON parsers are really complaining about — this error's family across 45 libraries.

Related errors


AI-assisted analysis of alibaba/spring-ai-alibaba@f82da0b50f (2026-09-09). Data as JSON: /api/errors/2978b51aceca0cee. Report an issue: GitHub.