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 inside syncDocuments when scheduling is set (i.e. the call came from prepareSelectedDocuments) and rt.embeddingHealth().enabled is false. Category 'action_forbidden', code 'copilot_selected_sources_unavailable'. It signals the embedding subsystem is down or disabled, so selected sources cannot be indexed for AI retrieval. (Without scheduling — the reconcile path — the method silently returns instead.)

Source

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

      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 26c515e050)

Solutions

  1. Verify the embedding backend configuration (endpoint, credentials) and that rt.embeddingHealth() reports enabled before offering 'select sources'.
  2. Retry after the embedding service recovers; if transient, treat as a temporary outage.
  3. Disable the source-selection UI when embeddingHealth is not enabled.

Example fix

// before: offer source selection regardless of health
await prepareSelectedDocuments(wsId, docIds);

// after: gate the UI on embedding health
const health = await getEmbeddingHealth();
if (!health.enabled) {
  show('AI source selection is temporarily unavailable.');
  return;
}
await prepareSelectedDocuments(wsId, docIds);
Defensive patterns

Strategy: validation

Validate before calling

const health = await rt.embeddingHealth();
if (!health.enabled) {
  show('AI source selection is temporarily unavailable.');
  return;
}
await prepareSelectedDocuments(workspaceId, docIds);

Type guard

function embeddingReady(h: { enabled: boolean }): boolean {
  return h.enabled === true;
}

Try / catch

try {
  await prepareSelectedDocuments(workspaceId, docIds);
} catch (e) {
  if (e.code === 'copilot_selected_sources_unavailable') {
    show('AI source selection is temporarily unavailable. Try again later.');
  } else throw e;
}

Prevention

When it happens

Trigger: prepareSelectedDocuments -> syncDocuments(..., { scheduling }) (job.ts:123-125) while the runtime embedding health check reports enabled === false.

Common situations: The embedding service/model is not configured or is unreachable (API key missing, vector DB down, model endpoint timing out); a feature flag disabling embeddings deployment-wide; startup race where the health check has not yet turned green.

Related errors


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