toeverything/AFFiNE · error · CommentAttachmentNotFound

comment_attachment_not_found

comment_attachment_not_found

Error message

Comment attachment not found.

What it means

Thrown when commentAttachmentStorage.get returns neither a redirectUrl nor a body for the requested comment attachment key. The attachment object is missing from storage.

Source

Thrown at packages/backend/server/src/core/workspaces/controller.ts:393

  @CallMetric('controllers', 'workspace_get_comment_attachment')
  async commentAttachment(
    @CurrentUser() user: CurrentUser,
    @Param('id') workspaceId: string,
    @Param('docId') docId: string,
    @Param('key') key: string,
    @Res() res: Response
  ) {
    await this.ac.user(user.id).doc(workspaceId, docId).assert('Doc.Read');

    const { body, metadata, redirectUrl } =
      await this.commentAttachmentStorage.get(workspaceId, docId, key, true);

    if (redirectUrl) {
      return res.redirect(redirectUrl);
    }

    if (!body) {
      throw new CommentAttachmentNotFound();
    }

    // metadata should always exists if body is not null
    if (metadata) {
      res.setHeader('content-type', metadata.contentType);
      res.setHeader('last-modified', metadata.lastModified.toUTCString());
      res.setHeader('content-length', metadata.contentLength);
    } else {
      this.logger.warn(
        `Comment attachment ${workspaceId}/${docId}/${key} has no metadata`
      );
    }
    applyAttachHeaders(res, {
      contentType: metadata?.contentType,
      filename: key,
    });

    res.setHeader('cache-control', 'private, max-age=2592000, immutable');

View on GitHub (pinned to 26c515e050)

Solutions

  1. Verify the key and that the attachment still exists.
  2. Re-upload the attachment if lost.
  3. Check comment-attachment storage health and lifecycle rules.
  4. Hide broken attachment UI gracefully.

Example fix

// before
const { body } = await commentAttachmentStorage.get(ws, docId, key)
return body
// after
const { body, redirectUrl } = await commentAttachmentStorage.get(ws, docId, key, true)
if (redirectUrl) return res.redirect(redirectUrl)
if (!body) throw new NotFound('comment attachment missing')
Defensive patterns

Strategy: validation

Validate before calling

const meta = await commentAttachmentStorage.head(workspaceId, docId, key)
if (!meta) return brokenAttachmentPlaceholder(key)

Try / catch

try { await loadCommentAttachment(key) } catch (e) {
  if (e.code === 'comment_attachment_not_found') showPlaceholder()
  else throw e
}

Prevention

When it happens

Trigger: Fetching a comment attachment by key when the object was deleted, never fully uploaded, or is not yet replicated.

Common situations: Attachment deleted with its comment; upload interrupted; object-store lifecycle removed it; wrong key.

Related errors


AI-assisted analysis of toeverything/AFFiNE@26c515e050 (2026-08-12). Data as JSON: /api/errors/6ab3b0dfaf620823. Report an issue: GitHub.