toeverything/AFFiNE · error · BlobNotFound

blob_not_found

blob_not_found

Error message

Blob ${blobId} not found in Space ${spaceId}.

What it means

Thrown after the storage layer returned no body (and no redirectUrl) for the requested blob name. The blob record may be absent, deleted, or not yet replicated to the object store.

Source

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

    const { body, metadata, redirectUrl } = await this.storage.get(
      workspaceId,
      name,
      true
    );

    if (redirectUrl) {
      // redirect to signed url
      if (redirect === 'manual') {
        return res.send({
          url: redirectUrl,
        });
      } else {
        return res.redirect(redirectUrl);
      }
    }

    if (!body) {
      throw new BlobNotFound({
        spaceId: workspaceId,
        blobId: name,
      });
    }

    // metadata should always exists if body is not null
    if (metadata) {
      res.setHeader(
        'content-type',
        metadata.contentType.startsWith('application/json') // application/json is reserved for redirect url
          ? 'text/json'
          : metadata.contentType
      );
      res.setHeader('last-modified', metadata.lastModified.toUTCString());
      res.setHeader('content-length', metadata.contentLength);
    } else {
      this.logger.warn(`Blob ${workspaceId}/${name} has no metadata`);
    }

View on GitHub (pinned to 26c515e050)

Solutions

  1. Verify the blob name is correct and the blob exists in storage.
  2. Re-upload the blob if it was lost.
  3. Check object storage lifecycle/replication and the blob record status.
  4. Retry shortly if this follows a fresh upload.

Example fix

// before
const { body } = await storage.get(ws, name)
return body
// after
const { body, redirectUrl } = await storage.get(ws, name, true)
if (redirectUrl) return res.redirect(redirectUrl)
if (!body) throw new NotFound('blob missing')
Defensive patterns

Strategy: validation

Validate before calling

const meta = await storage.head(workspaceId, name)
if (!meta) return placeholderAsset(name)

Try / catch

try { await loadBlob(ws, name) } catch (e) {
  if (e.code === 'blob_not_found') showPlaceholder()
  else throw e
}

Prevention

When it happens

Trigger: GET /workspaces/:id/blobs/:name passes access checks, storage returns a null body with no redirectUrl, so BlobNotFound is thrown.

Common situations: Blob was deleted; upload incomplete/corrupted record; object-store replication lag; wrong blob name; an expired object lifecycle rule removed it.

Related errors


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