toeverything/AFFiNE · error · BadRequestException

Local workspaces don't support attachments or references.

Error message

Local workspaces don't support attachments or references.

What it means

Thrown when a message carries workspace-scoped context (attachments, blobs, scopeSelectors, preferredSourceIds, or focus selectors) but session.config.workspaceId does not resolve to a workspace via models.workspace.get — i.e. the session is bound to a local (client-side) workspace the server has no record of. Local workspaces have no server-side blob/doc storage, so references cannot be resolved. It surfaces as a BadRequestException (HTTP 400).

Source

Thrown at packages/backend/server/src/plugins/copilot/conversation/inbox.ts:68

      options.blob ? [options.blob] : options.blobs || []
    );

    const focusSelectors = options.params?.focusSelectors;
    const hasWorkspaceContext =
      attachments.length > 0 ||
      blobs.length > 0 ||
      (Array.isArray(options.params?.scopeSelectors) &&
        options.params.scopeSelectors.length > 0) ||
      (Array.isArray(options.params?.preferredSourceIds) &&
        options.params.preferredSourceIds.length > 0) ||
      (focusSelectors === undefined
        ? session.config.focus.selectors.length > 0
        : Array.isArray(focusSelectors) && focusSelectors.length > 0);
    if (
      hasWorkspaceContext &&
      !(await this.models.workspace.get(session.config.workspaceId))
    ) {
      throw new BadRequestException(
        "Local workspaces don't support attachments or references."
      );
    }

    if (blobs.length) {
      await this.ac
        .user(userId)
        .workspace(session.config.workspaceId)
        .allowLocal()
        .assert('Workspace.Blobs.Write');
    }

    for (const blob of blobs) {
      const uploaded = await this.storage.handleUpload(userId, blob);
      const detectedMime =
        sniffMime(uploaded.buffer, blob.mimetype)?.toLowerCase() ||
        blob.mimetype;
      let attachmentBuffer = uploaded.buffer;

View on GitHub (pinned to b4c8548c09)

Solutions

  1. Strip attachments/blobs/scopeSelectors/preferredSourceIds/focusSelectors from the request when operating on a local workspace
  2. Enable cloud sync / sign in so the workspace exists server-side before attaching context
  3. Verify session.config.workspaceId is a cloud workspace id (models.workspace.get returns a record) before building the message
  4. In the UI, disable attachment and reference controls for local-workspace sessions

Example fix

// before
await inbox.createMessage(userId, {
  sessionId,
  blobs: [fileBlob], // local workspace -> 400
});

// after
const ws = await models.workspace.get(session.config.workspaceId);
if (!ws) {
  await inbox.createMessage(userId, { sessionId, content }); // plain prompt, no context
} else {
  await inbox.createMessage(userId, { sessionId, content, blobs: [fileBlob] });
}
Defensive patterns

Strategy: validation

Validate before calling

const isCloudWorkspace = !!(await models.workspace.get(session.config.workspaceId));
const hasContext =
  (options.attachments?.length ?? 0) > 0 ||
  (options.blobs?.length ?? 0) > 0 ||
  (options.params?.scopeSelectors?.length ?? 0) > 0 ||
  (options.params?.preferredSourceIds?.length ?? 0) > 0;
if (!isCloudWorkspace && hasContext) {
  delete options.attachments; delete options.blobs; delete options.params?.scopeSelectors; delete options.params?.preferredSourceIds;
}

Try / catch

try {
  return await inbox.createMessage(userId, options);
} catch (e) {
  if (e instanceof BadRequestException && /Local workspaces/.test(e.message)) {
    return inbox.createMessage(userId, { ...options, attachments: undefined, blobs: undefined });
  }
  throw e;
}

Prevention

When it happens

Trigger: Sending createMessage with blobs, attachments, scopeSelectors, preferredSourceIds, or non-empty focus selectors while the session's workspaceId is a local workspace id; local docs synced without a server workspace record; a workspace deleted server-side while the session still references it.

Common situations: Client enables file attachments in a local-only AFFiNE workspace; doc reference chips added in local mode; workspace was deleted but an old copilot session pinned its id.

Related errors


AI-assisted analysis of toeverything/AFFiNE@b4c8548c09 (2026-08-18). Data as JSON: /api/errors/1287a457ebaf1c3e. Report an issue: GitHub.