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
- Enable and configure the embedding backend runtime for the deployment and verify embeddingHealth().enabled becomes true.
- Check the backend-runtime provider configuration (endpoint/credentials/feature flags) in the server environment.
- 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
- Gate the selected-sources UI on the deployment's embedding health check.
- On self-hosted, verify embedding runtime configuration before enabling AI retrieval features.
- Never retry the same request - unavailability is a config state, not a transient fault.
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
- copilot_selected_sources_limit_exceeded
- blob_quota_exceeded
- copilot_embedding_unavailable
- access_denied
- action_bridge_stream_error
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)