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.

Solutions

  1. Verify tenantID, sessionID and documentID all match the values used at Create time
  2. Check whether the document expired or was cleaned up; re-upload if needed
  3. Treat as user-facing not-found and offer re-upload rather than retrying
  4. 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

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


AI-assisted analysis of Tencent/WeKnora@988cbb0330 (2026-09-02). Data as JSON: /api/errors/10a3c4f9b1bb72f1. Report an issue: GitHub.

Appendix: 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)