toeverything/AFFiNE · error · WorkspacePermissionNotFound

workspace_permission_not_found

workspace_permission_not_found

Error message

Space ${spaceId} permission not found.

What it means

unwrap maps errorCode 'permission_unavailable' to WorkspacePermissionNotFound, carrying the workspaceId. Unlike 'workspace_denied', this means the permission subsystem could not answer the access question at all while executing the search — the decision is unknown, not 'no'.

Source

Thrown at packages/backend/server/src/plugins/indexer/service.ts:151

    for (const doc of docs) {
      doc.createdByUser = users.get(doc.createdByUserId);
      doc.updatedByUser = users.get(doc.updatedByUserId);
    }
    return docs;
  }

  private unwrap<T>(output: SearchOperationOutput, workspaceId: string): T {
    if (output.ok) return output.value as T;
    switch (output.errorCode) {
      case 'workspace_denied':
        throw new SpaceAccessDenied({ spaceId: workspaceId });
      case 'invalid_request':
      case 'unsupported_query':
        throw new InvalidIndexerInput({ reason: output.errorCode });
      case 'provider_unavailable':
        throw new SearchProviderNotFound();
      case 'permission_unavailable':
        throw new WorkspacePermissionNotFound({ spaceId: workspaceId });
      default:
        throw new InternalServerError();
    }
  }
}

View on GitHub (pinned to 591f874dad)

Solutions

  1. Check server logs and health of the permission storage backing the search operation
  2. Verify the workspace exists and actually has permission records
  3. Retry once — transient storage errors surface through this code path
Defensive patterns

Strategy: retry

Validate before calling

// pre-flight the permission store before searching
const healthy = await permissionService.ping();
if (!healthy) return serviceUnavailable('permission storage unavailable');
return indexerService.search(user, { workspaceId, query });

Try / catch

// unknown-decision errors are transient: one bounded retry
try {
  return await search(user, workspaceId, query);
} catch (e) {
  if (e instanceof WorkspacePermissionNotFound) {
    await sleep(500);
    return search(user, workspaceId, query); // single retry, then surface 503
  }
  throw e;
}

Prevention

When it happens

Trigger: The permission lookup backing the search operation fails or finds no permission records for the workspace while a search is in flight.

Common situations: Permission storage (DB/service) briefly unreachable; workspace permission rows missing after a partial migration or data corruption; deployments where the permission service and indexer are scaled independently and one is down.

Related errors


AI-assisted analysis of toeverything/AFFiNE@591f874dad (2026-08-21). Data as JSON: /api/errors/13de81e7c7425289. Report an issue: GitHub.