chinabugotech/hutool · error · AIException
File not found!
Error message
File not found!
What it means
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.
Source
Thrown at hutool-ai/src/main/java/cn/hutool/ai/model/gemini/GeminiServiceImpl.java:166
@Override
public String textToSpeech(String prompt) {
final Map<String, Object> paramMap = buildTextToSpeechRequestMap(prompt);
final HttpResponse response = sendPost(getEndpoint(false), JSONUtil.toJsonStr(paramMap));
return response.body();
}
@Override
public String textToSpeech(String prompt, String voice) {
final Map<String, Object> voiceConfig = MapUtil.of("prebuilt_voice_config", MapUtil.of("voice_name", voice));
config.putAdditionalConfigByKey("speech_config", MapUtil.of("voice_config", voiceConfig));
return this.textToSpeech(prompt);
}
@Override
public String uploadFile(final File file) {
if (null == file || !file.exists()) {
throw new AIException("File not found!");
}
try {
//自动获取MIME
String mimeType = FileUtil.getMimeType(file.getName());
if (StrUtil.isBlank(mimeType)) {
mimeType = "application/octet-stream";
}
String uploadUrl = getUploadBaseUrl();
//获取 Upload URL
String metadata = JSONUtil.toJsonStr(MapUtil.of("file", MapUtil.of("display_name", file.getName())));
final HttpResponse res = HttpRequest.post(uploadUrl)
.header("x-goog-api-key", config.getApiKey())
.header("X-Goog-Upload-Protocol", "resumable")
.header("X-Goog-Upload-Command", "start")
.header("X-Goog-Upload-Header-Content-Length", String.valueOf(file.length()))
.header("X-Goog-Upload-Header-Content-Type", mimeType)View on GitHub (pinned to 8870454b2a)
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.
Example fix
// before
gemini.uploadFile(new File("/missing/dir/audio.mp3"));
// -> File not found!
// after
File f = new File(path);
if (f == null || !f.exists() || !f.canRead()) {
throw new IllegalArgumentException("audio file missing: " + path);
}
gemini.uploadFile(f); Defensive patterns
Strategy: validation
Validate before calling
// Existence + readability pre-check
if (file == null || !file.exists() || !file.canRead()) {
throw new IllegalArgumentException("file missing or unreadable: " + file);
}
gemini.uploadFile(file); Type guard
static boolean isUploadable(File f) {
return f != null && f.exists() && f.canRead();
} Try / catch
try {
gemini.uploadFile(file);
} catch (AIException e) {
if ("File not found!".equals(e.getMessage())) {
// path wrong / deleted -> resolve absolute path and retry
}
throw e;
} Prevention
- Always validate exists()/canRead() before calling uploadFile.
- Use absolute paths; for web uploads, materialize the temp file first.
- Guard against null explicitly.
When it happens
Trigger: 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.
Common situations: Web upload temp file already cleaned up; wrong absolute path; MultipartFile.transferTo not yet completed before calling uploadFile; typos in the path string.
Related errors
- Video URI is empty
- Paths or ins is empty !
- Paths length is not equals to ins length !
- Not a regular file!
- File path is blank!
AI-assisted analysis of chinabugotech/hutool@8870454b2a (2026-08-14).
Data as JSON: /api/errors/4e74818fe565a044.
Report an issue: GitHub.