Tencent/WeKnora · error
attachment not found
Error message
attachment not found
What it means
OpenFile looks up the document scoped to tenant+session+documentID; a nil result with no error means no matching attachment exists in that scope, and the service returns this error. It is a scoping-aware not-found: the document may exist but under a different tenant or session.
Source
Thrown at internal/application/service/temporary_document.go:254
if strings.TrimPrefix(strings.ToLower(strings.TrimSpace(fileType)), ".") == wanted {
return true
}
}
}
return false
}
func (s *temporaryDocumentService) Get(ctx context.Context, tenantID uint64, sessionID, documentID string) (*types.TemporaryDocument, error) {
return s.repo.GetScoped(ctx, tenantID, sessionID, documentID)
}
func (s *temporaryDocumentService) OpenFile(ctx context.Context, tenantID uint64, sessionID, documentID string) (io.ReadCloser, string, error) {
document, err := s.repo.GetScoped(ctx, tenantID, sessionID, documentID)
if err != nil {
return nil, "", err
}
if document == nil {
return nil, "", fmt.Errorf("attachment not found")
}
file, err := s.fileService.GetFile(ctx, document.ResourceRef)
if err != nil {
return nil, "", err
}
return file, document.FileName, nil
}
func (s *temporaryDocumentService) List(ctx context.Context, tenantID uint64, sessionID string) ([]*types.TemporaryDocument, error) {
return s.repo.ListScoped(ctx, tenantID, sessionID)
}
func (s *temporaryDocumentService) Delete(ctx context.Context, tenantID uint64, sessionID, documentID string) error {
document, err := s.repo.GetScoped(ctx, tenantID, sessionID, documentID)
if err != nil || document == nil {
return err
}
for _, ref := range temporaryDocumentImageRefs(document.ImageRefs) {View on GitHub (pinned to 988cbb0330)
Solutions
- Verify tenantID, sessionID and documentID all match the values used at Create time
- Check whether the document expired or was cleaned up; re-upload if needed
- Treat as user-facing not-found and offer re-upload rather than retrying
- Add logging of the lookup tuple to catch tenant/session mismatches
Example fix
// before
doc, err := repo.GetScoped(ctx, tenantID, sessionID, documentID)
if doc == nil { panic("missing") }
// after
doc, err := repo.GetScoped(ctx, tenantID, sessionID, documentID)
if doc == nil {
return ErrAttachmentNotFound // maps to 404 for the client
} Defensive patterns
Strategy: fallback
Validate before calling
// Caller-side: confirm the document was created and not expired in this session first.
if doc.ExpiresAt.Before(time.Now()) { return ErrAttachmentExpired } Type guard
func documentVisible(d *types.TemporaryDocument) bool { return d != nil && d.Status == types.TemporaryDocumentStatusReady } Try / catch
file, name, err := svc.OpenFile(ctx, tenantID, sessionID, documentID)
if err != nil && strings.Contains(err.Error(), "attachment not found") {
http.Error(w, "attachment not found", http.StatusNotFound)
return
} Prevention
- Return the full lookup tuple (tenant/session/document) in errors to debug scoping mismatches
- Expire client-side references when sessions end
- Map this error to 404, never 500
- Log tenantID with lookups to catch cross-tenant routing bugs
When it happens
Trigger: Opening a documentID that was already expired/purged; wrong sessionID paired with a valid documentID; cross-tenant access attempts where the ID exists in another tenant.
Common situations: Clients caching document IDs past session expiry; copy-pasting IDs between sessions; multi-tenant routing bugs sending the wrong tenantID.
Related errors
- join request not found
- rbac: resource not found
- knowledge service returned an empty result
- %w: %s
- mcp service not found
AI-assisted analysis of Tencent/WeKnora@988cbb0330 (2026-09-02).
Data as JSON: /api/errors/10a3c4f9b1bb72f1.
Report an issue: GitHub.