toeverything/AFFiNE · error · CopilotEmbeddingUnavailable

copilot_embedding_unavailable

copilot_embedding_unavailable

Error message

Embedding feature not available, you may need to install pgvector extension to your database

What it means

The addWorkspaceArtifact mutation requires embedding support. CopilotWorkspaceService.canEmbedding is only set when embedding.health() reports enabled at bootstrap, which for the default setup means the PostgreSQL pgvector extension is present and the embedding endpoint works. Otherwise the resolver throws CopilotEmbeddingUnavailable (action_forbidden, code copilot_embedding_unavailable).

Source

Thrown at packages/backend/server/src/plugins/copilot/workspace/resolver.ts:169

    name: 'addWorkspaceArtifact',
    complexity: 2,
    description: 'Add a workspace artifact',
  })
  async addArtifact(
    @Context() ctx: { req: Request },
    @CurrentUser() user: CurrentUser,
    @Args('workspaceId', { type: () => String })
    workspaceId: string,
    @Args({ name: 'blob', type: () => GraphQLUpload })
    content: FileUpload
  ): Promise<CopilotWorkspaceArtifactType> {
    await this.ac
      .user(user.id)
      .workspace(workspaceId)
      .assert('Workspace.Settings.Update');

    if (!this.copilotWorkspace.canEmbedding) {
      throw new CopilotEmbeddingUnavailable();
    }

    const lockFlag = `${COPILOT_LOCKER}:workspace:${workspaceId}`;
    await using lock = await this.mutex.acquire(lockFlag);
    if (!lock) {
      throw new TooManyRequest('Server is busy');
    }

    const length = Number(ctx.req.headers['content-length']);
    if (length && length >= MAX_EMBEDDABLE_SIZE) {
      throw new BlobQuotaExceeded();
    }

    try {
      return await this.copilotWorkspace.addArtifact(workspaceId, content);
    } catch (e) {
      // passthrough user friendly error
      if (e instanceof UserFriendlyError) {

View on GitHub (pinned to b4c8548c09)

Solutions

  1. Run CREATE EXTENSION vector; on the database (or switch to a pgvector-enabled Postgres image) and restart the server
  2. Verify the copilot embedding provider config (endpoint/keys) is correct so health() passes on next boot
  3. After restart, confirm the CopilotEmbedding feature appears in the server's enabled features before calling the mutation

Example fix

# before (docker-compose)
image: postgres:16

# after
image: pgvector/pgvector:pg16
# then: CREATE EXTENSION vector; in the DB and restart the server
Defensive patterns

Strategy: validation

Validate before calling

const info = await client.getServerInfo();
if (!info.features.includes('CopilotEmbedding')) {
  throw new Error('embedding unavailable: install pgvector / fix embedding config on the server');
}
await mutate({ workspaceId, blob });

Type guard

const canUseWorkspaceArtifacts = (features: string[]): boolean =>
  features.includes('CopilotEmbedding');

Try / catch

try {
  await mutate({ workspaceId, blob });
} catch (e) {
  if (e?.code === 'copilot_embedding_unavailable') {
    // server-side fix required: CREATE EXTENSION vector; then restart
    showSetupHint('pgvector required');
  } else throw e;
}

Prevention

When it happens

Trigger: Invoking addWorkspaceArtifact (or other embedding-dependent workspace APIs) on a server where pgvector is not installed in PostgreSQL, the extension was not created in the database, or the copilot embedding provider configuration is disabled/unreachable so onApplicationBootstrap never set supportEmbedding.

Common situations: Self-hosting AFFiNE on the stock postgres image instead of pgvector/pgvector; managed Postgres without the vector extension; copilot embedding env vars unset; checking the flag before the bootstrap health check completed.

Related errors


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