{"record":{"id":"485f11b2d2d93ce1","repo":"alibaba/spring-ai-alibaba","slug":"file-variable-not-found-for-selector","errorCode":null,"errorMessage":"File variable not found for selector","messagePattern":"File variable not found for selector","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"spring-boot-starters/spring-ai-alibaba-starter-builtin-nodes/src/main/java/com/alibaba/cloud/ai/graph/node/DocumentExtractorNode.java","lineNumber":118,"sourceCode":"\t\t\treturn new BufferedInputStream(uri.toURL().openStream());\n\t\t}\n\t}\n\n\tprivate List<String> getDocument(List<String> fileList) {\n\t\treturn fileList.stream().map(String::trim).map(file -> {\n\t\t\ttry (InputStream inputStream = this.getInputStream(file.trim())) {\n\t\t\t\treturn this.extractTextByFileExtension(inputStream, getFileExtension(file));\n\t\t\t}\n\t\t\tcatch (Exception e) {\n\t\t\t\tthrow new RuntimeException(\"Failed to parse test file: \" + file, e);\n\t\t\t}\n\t\t}).toList();\n\t}\n\n\t@Override\n\tpublic Map<String, Object> apply(OverAllState state) throws Exception {\n\t\tif (paramsKey == null && fileList == null) {\n\t\t\tthrow new RuntimeException(\"File variable not found for selector\");\n\t\t}\n\t\tList<String> fileList;\n\t\tObject fileObj = state.value(paramsKey).orElse(this.fileList);\n\t\tif (this.inputIsArray) {\n\t\t\tif (fileObj instanceof List<?>) {\n\t\t\t\tfileList = (List<String>) fileObj;\n\t\t\t}\n\t\t\telse if (fileObj instanceof String[]) {\n\t\t\t\tfileList = Arrays.asList((String[]) fileObj);\n\t\t\t}\n\t\t\telse {\n\t\t\t\t// Try to parse as Json string, if failed the input is invalid\n\t\t\t\ttry {\n\t\t\t\t\tfileList = JsonParser.fromJson(fileObj.toString(), new TypeReference<List<String>>() {\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tcatch (Exception ignore) {\n\t\t\t\t\tfileList = null;","sourceCodeStart":100,"sourceCodeEnd":136,"githubUrl":"https://github.com/alibaba/spring-ai-alibaba/blob/f82da0b50f35744c13968191be2b1cd2452ef550/spring-boot-starters/spring-ai-alibaba-starter-builtin-nodes/src/main/java/com/alibaba/cloud/ai/graph/node/DocumentExtractorNode.java#L100-L136","documentation":"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.","triggerScenarios":"Building DocumentExtractorNode without setting paramsKey or fileList, and then executing apply on a state that likewise contains no value under a paramsKey.","commonSituations":"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.","solutions":["Set paramsKey (state key that holds the file list) on the DocumentExtractorNode builder, or provide a static fileList","Ensure the upstream node writes files to the exact state key named by paramsKey","Add a validation/assertion step before the extractor that the key exists in state"],"exampleFix":"// before\nDocumentExtractorNode node = DocumentExtractorNode.builder().outputKey(\"text\").build();\n// after\nDocumentExtractorNode node = DocumentExtractorNode.builder()\n    .paramsKey(\"upload_files\")\n    .outputKey(\"text\")\n    .build();","handlingStrategy":"validation","validationCode":"if (builderParamsKey == null && builderFileList == null) {\n    throw new ConfigException(\"DocumentExtractorNode needs paramsKey or fileList\");\n}","typeGuard":"static boolean hasFileSource(DocumentExtractorNode n, OverAllState s) {\n    return n.paramsKey != null || n.fileList != null || s.value(n.paramsKey).isPresent();\n}","tryCatchPattern":"try {\n    out = extractorNode.apply(state);\n} catch (RuntimeException e) {\n    throw new WorkflowConfigException(\"Extractor has no file source: set paramsKey or fileList\", e);\n}","preventionTips":["Always configure paramsKey or fileList in the builder","Confirm the upstream node writes to exactly the same state key name","Add a graph-definition lint that fails nodes lacking a file source"],"tags":["document-extraction","missing-config","state-key"],"backgroundTag":"missing-required-config-field","analyzedSha":"f82da0b50f35744c13968191be2b1cd2452ef550","analyzedAt":"2026-09-09T15:32:42.421Z","contentChangedAt":"2026-09-09T15:32:42.421Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}