OtterMind/Chat2DB · error · BusinessException

ai.attachment.fileNotFound

ai.attachment.fileNotFound

Error message

ai.attachment.fileNotFound

What it means

Thrown by AiAttachmentServiceImpl.parse(AiLocalAttachmentParseRequest) after constructing new File(filePath.trim()) when the path does not exist or is not a regular file (e.g. it points at a directory). The i18n message resolves to 'File does not exist'. It is a pre-parse guard so the service never opens a missing or non-file target.

Source

Thrown at chat2db-community-server/chat2db-community-domain/chat2db-community-domain-core/src/main/java/ai/chat2db/community/domain/core/impl/ai/AiAttachmentServiceImpl.java:72

    public ChatAttachment parse(AiAttachmentParseRequest param) {
        if (param == null || param.getInputStream() == null) {
            throw new BusinessException("ai.attachment.inputStreamRequired");
        }
        String fileName = StringUtils.defaultIfBlank(param.getFileName(), "attachment");
        try (InputStream inputStream = param.getInputStream()) {
            return parse(fileName, inputStream);
        } catch (IOException e) {
            throw new BusinessException("ai.attachment.parseFailed", new Object[]{fileName, e.getMessage()}, e);
        }
    }

    public ChatAttachment parse(AiLocalAttachmentParseRequest param) {
        if (param == null || StringUtils.isBlank(param.getFilePath())) {
            throw new BusinessException("ai.attachment.filePathRequired");
        }
        File file = new File(param.getFilePath().trim());
        if (!file.exists() || !file.isFile()) {
            throw new BusinessException("ai.attachment.fileNotFound");
        }
        String fileName = StringUtils.defaultIfBlank(param.getFileName(), file.getName());
        try (InputStream inputStream = new FileInputStream(file)) {
            return parse(fileName, inputStream);
        } catch (IOException e) {
            throw new BusinessException("ai.attachment.localParseFailed", new Object[]{file.getPath(), e.getMessage()}, e);
        }
    }

    public String buildStructuredContext(List<ChatAttachment> attachments) {
        if (CollectionUtils.isEmpty(attachments)) {
            return null;
        }
        StringBuilder builder = new StringBuilder(4096);
        builder.append("Uploaded file context for the current conversation. ");
        builder.append("Treat it as user-provided evidence. ");
        builder.append("If the parsed content is truncated, say so when it affects certainty.\n");

View on GitHub (pinned to 5ee1e990e7)

Solutions

  1. Verify the file exists at the server path before calling parse(), and re-check the temp-upload lifecycle so the file is not GC'd early.
  2. Use absolute server paths; never pass client machine paths from the renderer to the server-side local parse overload.
  3. If the upload produced an InputStream, switch to parse(AiAttachmentParseRequest) which does not require an existing server file.

Example fix

// before
req.setFilePath(tempPath); // tempPath already deleted
service.parse(req);

// after
File f = new File(tempPath);
if (!f.isFile()) {
    return ResponseEntity.badRequest().body("file is missing, re-upload");
}
req.setFilePath(f.getAbsolutePath());
service.parse(req);
Defensive patterns

Strategy: validation

Validate before calling

File f = new File(param.getFilePath().trim());
if (!f.exists() || !f.isFile()) {
    return ResponseEntity.badRequest().body("file does not exist: " + f);
}
service.parse(param);

Try / catch

try {
    service.parse(param);
} catch (BusinessException e) {
    if ("ai.attachment.fileNotFound".equals(e.getCode())) {
        return ResponseEntity.badRequest().body("re-upload the file");
    }
    throw e;
}

Prevention

When it happens

Trigger: param.getFilePath() resolves to a path that does not exist on the server filesystem, OR points to a directory, OR the path was a temporary upload that was already cleaned up. Triggered by: new File(param.getFilePath().trim()) where !file.exists() || !file.isFile().

Common situations: Temp upload file was deleted between the upload and parse call; the desktop renderer passed a client-side path that does not exist on the server; a relative path resolved against an unexpected working directory; the path points to a folder rather than a file; stale path cached after a move/rename.

Related errors


AI-assisted analysis of OtterMind/Chat2DB@5ee1e990e7 (2026-08-14). Data as JSON: /api/errors/8e4ba1cf13d2ba3f. Report an issue: GitHub.