{"record":{"id":"03b09ff68eae5a2b","repo":"alibaba/spring-ai-alibaba","slug":"unsupported-extension-type-fileextension","errorCode":null,"errorMessage":"Unsupported Extension Type: {fileExtension}","messagePattern":"Unsupported Extension Type: (.+?)","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":162,"sourceCode":"\t\t\t// Single file, add directly to the list\n\t\t\tfileList = List.of(fileObj.toString());\n\t\t}\n\t\tList<String> documentContents = this.getDocument(fileList);\n\n\t\tString key = Optional.ofNullable(this.outputKey).orElse(\"text\");\n\t\tif (!this.inputIsArray) {\n\t\t\treturn Map.of(key, documentContents.get(0));\n\t\t}\n\t\telse {\n\t\t\treturn Map.of(key, documentContents);\n\t\t}\n\t}\n\n\tprivate String extractTextByFileExtension(InputStream fileContent, String fileExtension) {\n\n\t\tFunction<InputStream, List<Document>> extractor = this.extractors.get(fileExtension);\n\t\tif (extractor == null) {\n\t\t\tthrow new RuntimeException(\"Unsupported Extension Type: \" + fileExtension);\n\t\t}\n\n\t\treturn extractor.apply(fileContent).get(0).getText();\n\t}\n\n\tprivate String getFileExtension(String filePath) {\n\t\tPath path = Paths.get(filePath);\n\t\tString fileName = path.getFileName().toString();\n\t\tint dotIndex = fileName.lastIndexOf('.');\n\n\t\treturn (dotIndex == -1) ? \"\" : fileName.substring(dotIndex + 1);\n\t}\n\n\tpublic static Builder builder() {\n\t\treturn new Builder();\n\t}\n\n\tpublic static class Builder {","sourceCodeStart":144,"sourceCodeEnd":180,"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#L144-L180","documentation":"DocumentExtractorNode.extractTextByFileExtension looks up a parsing Function in an internal map keyed by lowercase file extension (pdf, docx, txt, html, etc.). If the extension is missing from the map — because the document format is not one of the built-in supported types — it throws this RuntimeException. It is a fail-fast guard against unsupported file formats rather than a parsing failure.","triggerScenarios":"Calling getDocument/extractTextByFileExtension with a file whose extension (or derived key) is not registered in the extractors map: e.g. .md, .csv, .pptx, .xlsx, .rtf, or a file with no extension at all; also a wrong/mispelled extension passed explicitly.","commonSituations":"Users point the DocumentExtractor node at knowledge-base files in formats outside the supported set (Markdown, CSV, PowerPoint); files uploaded without extensions; case or whitespace issues in the extension key.","solutions":["Convert the document to a supported format (PDF, DOCX, TXT, HTML) before extraction.","Check the extension actually matches one of the registered extractors (inspect the extractors map keys in DocumentExtractorNode).","Log/verify the value of getFileExtension(filePath) — strip leading dots and normalize case.","Register a custom extractor for the extension in the extractors map if extending the node.","Return a clear validation error to the workflow user before the node runs."],"exampleFix":"// before\nFunction<InputStream, List<Document>> extractor = this.extractors.get(fileExtension);\nif (extractor == null) {\n    throw new RuntimeException(\"Unsupported Extension Type: \" + fileExtension);\n}\n// after\nString key = fileExtension == null ? \"\" : fileExtension.toLowerCase().replaceAll(\"^\\\\.\", \"\");\nFunction<InputStream, List<Document>> extractor = this.extractors.get(key);\nif (extractor == null) {\n    throw new IllegalArgumentException(\"Unsupported Extension Type: \" + key\n        + \"; supported: \" + this.extractors.keySet());\n}","handlingStrategy":"validation","validationCode":"Set<String> supported = Set.of(\"pdf\",\"docx\",\"txt\",\"html\");\nString ext = Optional.ofNullable(path)\n    .map(p -> p.substring(p.lastIndexOf('.') + 1).toLowerCase())\n    .orElse(\"\");\nif (!supported.contains(ext)) throw new IllegalStateException(\"Unsupported extension: \" + ext);","typeGuard":"boolean isSupported(String ext) {\n    return ext != null && extractors.containsKey(ext.toLowerCase().replaceAll(\"^\\\\.\", \"\"));\n}","tryCatchPattern":"try {\n    String text = node.getDocument(state);\n} catch (RuntimeException e) {\n    if (e.getMessage().startsWith(\"Unsupported Extension Type\")) {\n        log.warn(\"Skipping unsupported document: {}\", e.getMessage());\n    } else throw e;\n}","preventionTips":["Normalize extensions (lowercase, strip leading dot) before extraction.","Whitelist allowed formats at workflow ingestion time.","Convert unsupported formats upstream (e.g. md->pdf) before the extractor node.","Log the resolved extension when building the node for easier debugging."],"tags":["unsupported-file-format","document-extraction","runtime-exception"],"backgroundTag":"unsupported-operation","analyzedSha":"f82da0b50f35744c13968191be2b1cd2452ef550","analyzedAt":"2026-09-09T15:32:42.421Z","contentChangedAt":"2026-09-09T15:32:42.421Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}