toeverything/AFFiNE · error · CopilotSelectedSourcesUnavailable

copilot_selected_sources_unavailable

copilot_selected_sources_unavailable

Error message

Selected sources are not available for AI retrieval.

What it means

Thrown from syncDocuments (job.ts:123-125) when preparing user-selected sources: this.rt.embeddingHealth() reports the embedding backend as not enabled, so selected-source retrieval cannot be served. It is an 'action_forbidden' error: background embedding sync silently skips (scheduling unset), but an explicit user selection fails loudly.

Solutions

  1. Enable and configure the embedding backend runtime for the deployment and verify embeddingHealth().enabled becomes true.
  2. Check the backend-runtime provider configuration (endpoint/credentials/feature flags) in the server environment.
  3. If embeddings are intentionally off, stop sending retrieval scope mode 'required' and chat without selected sources.
Defensive patterns

Strategy: try-catch

Validate before calling

const health = await backendRuntime.embeddingHealth();
if (!health.enabled) {
  // hide 'required' retrieval option; chat without selected sources
}

Try / catch

try {
  await prepareSelectedDocuments(workspaceId, requiredDocIds);
} catch (e) {
  if (getErrorCode(e) === 'copilot_selected_sources_unavailable') {
    // surface 'AI retrieval unavailable' and fall back to plain chat without retrieval scope
  } else throw e;
}

Prevention

When it happens

Trigger: prepareSelectedDocuments -> syncDocuments with scheduling set, while the backend runtime's embedding health endpoint returns enabled=false (embedding runtime not deployed, not configured, or unhealthy).

Common situations: Self-hosted deployment without the embedding runtime configured; embedding capability disabled at the instance level; missing credentials/endpoint for the backend runtime so the health check reports disabled.

Related errors


AI-assisted analysis of toeverything/AFFiNE@2af30773ae (2026-08-18). Data as JSON: /api/errors/42f319f9d92675ff. Report an issue: GitHub.

Appendix: source

Thrown at packages/backend/server/src/core/backend-runtime/job.ts:72

      return new CopilotSelectedSourcesProcessing();
    }
    if (message.includes('embedding_selected_sources_failed')) {
      return new CopilotSelectedSourcesFailed();
    }
    if (message.includes('embedding_selected_sources_unavailable')) {
      return new CopilotSelectedSourcesUnavailable();
    }
    return error;
  }

  private async syncDocuments(
    workspaceId: string,
    docIds: string[],
    reconcileDocuments: boolean,
    scheduling?: { priority: number; waitForReadyMs: number }
  ) {
    if (!(await this.rt.embeddingHealth()).enabled) {
      if (scheduling) throw new CopilotSelectedSourcesUnavailable();
      return;
    }
    const enabled = await this.models.workspace.allowEmbedding(workspaceId);
    if (!enabled) {
      if (scheduling) throw new CopilotSelectedSourcesUnavailable();
      return;
    }
    const documents = [];
    let unitCount = 0;
    let textBytes = 0;
    for (const docId of docIds) {
      const snapshot = await this.models.doc.getSnapshot(workspaceId, docId);
      if (!snapshot) {
        if (scheduling) throw new CopilotSelectedSourcesUnavailable();
        continue;
      }
      const revision = snapshot.updatedAt.getTime().toString();
      const projection = projectDocSearch(snapshot.blob, docId, revision);

View on GitHub (pinned to 2af30773ae)