alibaba/spring-ai-alibaba · error · RuntimeException

Variable fileList is not an ArrayFileSegment

Error message

Variable fileList is not an ArrayFileSegment

What it means

DocumentExtractorNode.apply throws this RuntimeException in the inputIsArray branch when, after attempting to coerce the state value, fileList is null or empty — i.e. the value at paramsKey was not a usable ArrayFileSegment (list of file segments).

Solutions

  1. Make the upstream node emit an ArrayFileSegment (list of file segments) under paramsKey
  2. Set inputIsArray=false if the input is actually a single file
  3. Log/inspect the actual type of state.value(paramsKey) and align it with the extractor's expectation

Example fix

// before
state.put("files", singleFileString); // node has inputIsArray=true
// after
state.put("files", List.of(fileSegment1, fileSegment2));
Defensive patterns

Strategy: type-guard

Validate before calling

Object v = state.value(paramsKey).orElse(null);
if (inputIsArray && !(v instanceof List<?> list && !list.isEmpty())) {
    throw new IllegalStateException("paramsKey must hold a non-empty ArrayFileSegment list");
}

Type guard

static boolean isArrayFileSegment(Object v) {
    return v instanceof List<?> l && !l.isEmpty() && l.get(0) instanceof FileSegment;
}

Try / catch

try {
    out = extractorNode.apply(state);
} catch (RuntimeException e) {
    logger.error("fileList shape wrong: {}", e.getMessage());
    out = Map.of(outputKey, List.of());
}

Prevention

When it happens

Trigger: inputIsArray=true but the state value under paramsKey is a single string, a Map, or an object that fails conversion to a list of files, leaving fileList null after the catch block sets it to null.

Common situations: Upstream node writes a single file string while the extractor expects an array of ArrayFileSegment; state key never populated; shape change after upgrading the file-segment representation; JSON-deserialized state loses the segment type.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


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

Appendix: source

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

		if (this.inputIsArray) {
			if (fileObj instanceof List<?>) {
				fileList = (List<String>) fileObj;
			}
			else if (fileObj instanceof String[]) {
				fileList = Arrays.asList((String[]) fileObj);
			}
			else {
				// Try to parse as Json string, if failed the input is invalid
				try {
					fileList = JsonParser.fromJson(fileObj.toString(), new TypeReference<List<String>>() {
					});
				}
				catch (Exception ignore) {
					fileList = null;
				}
			}
			if (fileList == null || fileList.isEmpty()) {
				throw new RuntimeException("Variable fileList is not an ArrayFileSegment");
			}
		}
		else {
			// Single file, add directly to the list
			fileList = List.of(fileObj.toString());
		}
		List<String> documentContents = this.getDocument(fileList);

		String key = Optional.ofNullable(this.outputKey).orElse("text");
		if (!this.inputIsArray) {
			return Map.of(key, documentContents.get(0));
		}
		else {
			return Map.of(key, documentContents);
		}
	}

	private String extractTextByFileExtension(InputStream fileContent, String fileExtension) {

View on GitHub (pinned to f82da0b50f)