{"record":{"id":"4e74818fe565a044","repo":"chinabugotech/hutool","slug":"file-not-found","errorCode":null,"errorMessage":"File not found!","messagePattern":"File not found!","errorType":"validation","errorClass":"AIException","httpStatus":null,"severity":"error","filePath":"hutool-ai/src/main/java/cn/hutool/ai/model/gemini/GeminiServiceImpl.java","lineNumber":166,"sourceCode":"\n\t@Override\n\tpublic String textToSpeech(String prompt) {\n\t\tfinal Map<String, Object> paramMap = buildTextToSpeechRequestMap(prompt);\n\t\tfinal HttpResponse response = sendPost(getEndpoint(false), JSONUtil.toJsonStr(paramMap));\n\t\treturn response.body();\n\t}\n\n\t@Override\n\tpublic String textToSpeech(String prompt, String voice) {\n\t\tfinal Map<String, Object> voiceConfig = MapUtil.of(\"prebuilt_voice_config\", MapUtil.of(\"voice_name\", voice));\n\t\tconfig.putAdditionalConfigByKey(\"speech_config\", MapUtil.of(\"voice_config\", voiceConfig));\n\t\treturn this.textToSpeech(prompt);\n\t}\n\n\t@Override\n\tpublic String uploadFile(final File file) {\n\t\tif (null == file || !file.exists()) {\n\t\t\tthrow new AIException(\"File not found!\");\n\t\t}\n\t\ttry {\n\t\t\t//自动获取MIME\n\t\t\tString mimeType = FileUtil.getMimeType(file.getName());\n\t\t\tif (StrUtil.isBlank(mimeType)) {\n\t\t\t\tmimeType = \"application/octet-stream\";\n\t\t\t}\n\n\t\t\tString uploadUrl = getUploadBaseUrl();\n\n\t\t\t//获取 Upload URL\n\t\t\tString metadata = JSONUtil.toJsonStr(MapUtil.of(\"file\", MapUtil.of(\"display_name\", file.getName())));\n\t\t\tfinal HttpResponse res = HttpRequest.post(uploadUrl)\n\t\t\t\t.header(\"x-goog-api-key\", config.getApiKey())\n\t\t\t\t.header(\"X-Goog-Upload-Protocol\", \"resumable\")\n\t\t\t\t.header(\"X-Goog-Upload-Command\", \"start\")\n\t\t\t\t.header(\"X-Goog-Upload-Header-Content-Length\", String.valueOf(file.length()))\n\t\t\t\t.header(\"X-Goog-Upload-Header-Content-Type\", mimeType)","sourceCodeStart":148,"sourceCodeEnd":184,"githubUrl":"https://github.com/chinabugotech/hutool/blob/8870454b2a0c29cc6ffd31dcf5667c8ceb2fc442/hutool-ai/src/main/java/cn/hutool/ai/model/gemini/GeminiServiceImpl.java#L148-L184","documentation":"A precondition violation thrown by GeminiServiceImpl.uploadFile(File) when the file argument is null or file.exists() is false. No network call is made; the guard fails before any upload logic. It means the caller passed a non-existent path.","triggerScenarios":"Passing null for the file argument; passing a File whose path does not exist on disk; passing a relative path resolved against an unexpected working directory; the file was deleted between selection and upload.","commonSituations":"Web upload temp file already cleaned up; wrong absolute path; MultipartFile.transferTo not yet completed before calling uploadFile; typos in the path string.","solutions":["Validate file != null && file.exists() (and isReadable) before calling uploadFile.","Use absolute paths and confirm they exist at call time.","For web uploads, ensure the temp file is materialized on disk first."],"exampleFix":"// before\ngemini.uploadFile(new File(\"/missing/dir/audio.mp3\"));\n// -> File not found!\n\n// after\nFile f = new File(path);\nif (f == null || !f.exists() || !f.canRead()) {\n    throw new IllegalArgumentException(\"audio file missing: \" + path);\n}\ngemini.uploadFile(f);","handlingStrategy":"validation","validationCode":"// Existence + readability pre-check\nif (file == null || !file.exists() || !file.canRead()) {\n    throw new IllegalArgumentException(\"file missing or unreadable: \" + file);\n}\ngemini.uploadFile(file);","typeGuard":"static boolean isUploadable(File f) {\n    return f != null && f.exists() && f.canRead();\n}","tryCatchPattern":"try {\n    gemini.uploadFile(file);\n} catch (AIException e) {\n    if (\"File not found!\".equals(e.getMessage())) {\n        // path wrong / deleted -> resolve absolute path and retry\n    }\n    throw e;\n}","preventionTips":["Always validate exists()/canRead() before calling uploadFile.","Use absolute paths; for web uploads, materialize the temp file first.","Guard against null explicitly."],"tags":["validation","gemini","file","precondition"],"backgroundTag":null,"analyzedSha":"8870454b2a0c29cc6ffd31dcf5667c8ceb2fc442","analyzedAt":"2026-08-14T04:01:12.892Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}