alibaba/spring-ai-alibaba · error · RuntimeException

File variable not found for selector

Error message

File variable not found for selector

What it means

DocumentExtractorNode.apply throws this RuntimeException when neither paramsKey nor a configured fileList is set, so the node has no source for the files to extract. The node requires either a state key holding the file list or a constructor-provided file list.

Solutions

  1. Set paramsKey (state key that holds the file list) on the DocumentExtractorNode builder, or provide a static fileList
  2. Ensure the upstream node writes files to the exact state key named by paramsKey
  3. Add a validation/assertion step before the extractor that the key exists in state

Example fix

// before
DocumentExtractorNode node = DocumentExtractorNode.builder().outputKey("text").build();
// after
DocumentExtractorNode node = DocumentExtractorNode.builder()
    .paramsKey("upload_files")
    .outputKey("text")
    .build();
Defensive patterns

Strategy: validation

Validate before calling

if (builderParamsKey == null && builderFileList == null) {
    throw new ConfigException("DocumentExtractorNode needs paramsKey or fileList");
}

Type guard

static boolean hasFileSource(DocumentExtractorNode n, OverAllState s) {
    return n.paramsKey != null || n.fileList != null || s.value(n.paramsKey).isPresent();
}

Try / catch

try {
    out = extractorNode.apply(state);
} catch (RuntimeException e) {
    throw new WorkflowConfigException("Extractor has no file source: set paramsKey or fileList", e);
}

Prevention

When it happens

Trigger: Building DocumentExtractorNode without setting paramsKey or fileList, and then executing apply on a state that likewise contains no value under a paramsKey.

Common situations: Forgetting to configure the file source in the node builder; upstream node writes files under a different state key than paramsKey; refactor renamed the state key without updating the extractor node.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


AI-assisted analysis of alibaba/spring-ai-alibaba@f82da0b50f (2026-09-09). Data as JSON: /api/errors/485f11b2d2d93ce1. 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:118

			return new BufferedInputStream(uri.toURL().openStream());
		}
	}

	private List<String> getDocument(List<String> fileList) {
		return fileList.stream().map(String::trim).map(file -> {
			try (InputStream inputStream = this.getInputStream(file.trim())) {
				return this.extractTextByFileExtension(inputStream, getFileExtension(file));
			}
			catch (Exception e) {
				throw new RuntimeException("Failed to parse test file: " + file, e);
			}
		}).toList();
	}

	@Override
	public Map<String, Object> apply(OverAllState state) throws Exception {
		if (paramsKey == null && fileList == null) {
			throw new RuntimeException("File variable not found for selector");
		}
		List<String> fileList;
		Object fileObj = state.value(paramsKey).orElse(this.fileList);
		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;

View on GitHub (pinned to f82da0b50f)