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
- Check server logs and health of the permission storage backing the search operation
- Verify the workspace exists and actually has permission records
- 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
- Monitor permission-storage errors separately from explicit denials — they need different response codes (503 vs 403)
- Alert when 'permission_unavailable' rate rises; it precedes user-visible search outages
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
- space_access_denied
- invalid_indexer_input
- search_provider_not_found
- internal_server_error
- space_access_denied
AI-assisted analysis of toeverything/AFFiNE@591f874dad (2026-08-21).
Data as JSON: /api/errors/13de81e7c7425289.
Report an issue: GitHub.