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
- Verify the embedding backend configuration (endpoint, credentials) and that rt.embeddingHealth() reports enabled before offering 'select sources'.
- Retry after the embedding service recovers; if transient, treat as a temporary outage.
- 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
- Hide/disable source selection when embeddingHealth.enabled is false.
- Monitor the embedding backend and alert before it goes unhealthy.
- Treat the unavailable error as transient and allow retry once the health check recovers.
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
- copilot_selected_sources_limit_exceeded
- internal_server_error
- copilot_prompt_invalid
- copilot_session_deleted
- copilot_session_not_found
AI-assisted analysis of toeverything/AFFiNE@26c515e050 (2026-08-12).
Data as JSON: /api/errors/42f319f9d92675ff.
Report an issue: GitHub.