toeverything/AFFiNE · error · SpaceNotFound
space_not_found
space_not_found
Error message
Space ${spaceId} not found. What it means
Thrown by the workspace(id) GraphQL query when the caller passes the Workspace.Read access assertion but models.workspace.get(id) returns null — no workspace with that id exists (deleted or never existed).
Solutions
- Re-fetch the user's workspace list and use a current workspace id.
- Confirm the id is the exact workspace identifier (no encoding issues, no doc id passed instead of workspace id).
- If the workspace was deleted unexpectedly, check the deletion audit/records.
Defensive patterns
Strategy: try-catch
Validate before calling
// Before deep-linking, confirm the id is in the user's workspace list
const list = await gql.request(GET_WORKSPACES);
if (!list.workspaces.some(w => w.id === targetId)) {
router.replace('/404');
} Type guard
const isSpaceNotFound = (e: unknown): boolean => getGraphqlErrorCode(e) === 'space_not_found';
Try / catch
try {
const { workspace } = await gql.request(GET_WORKSPACE, { id });
} catch (e) {
if (isSpaceNotFound(e)) router.replace('/404');
} Prevention
- Validate workspace ids against a fresh workspace-list query before navigating or persisting them.
- Drop stored workspace ids that 404 so stale references don't recur.
When it happens
Trigger: Querying workspace(id: "...") with a deleted, malformed, or random id that the user happens to be allowed to assert on.
Common situations: Client holds a stale workspace id after deletion (page/doc bookmark), ids copied with whitespace or truncation, or scripts iterating ids that were cleaned up.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- Workspace not found
- authentication_required
- comment_not_found
- copilot_session_not_found
- copilot_transcription_job_not_found
AI-assisted analysis of toeverything/AFFiNE@2af30773ae (2026-08-18).
Data as JSON: /api/errors/a6bc5f668e274ac8.
Report an issue: GitHub.
Appendix: source
Thrown at packages/backend/server/src/core/workspaces/resolvers/workspace.ts:176
);
return workspaces.map(workspace => ({
...workspace,
permission: map.get(workspace.id),
role: map.get(workspace.id),
}));
}
@Query(() => WorkspaceType, {
description: 'Get workspace by id',
})
async workspace(@CurrentUser() user: CurrentUser, @Args('id') id: string) {
await this.ac.user(user.id).workspace(id).assert('Workspace.Read');
const workspace = await this.models.workspace.get(id);
if (!workspace) {
throw new SpaceNotFound({ spaceId: id });
}
return workspace;
}
@Query(() => WorkspaceRolePermissions, {
description: 'Get workspace role permissions',
deprecationReason: 'use WorkspaceType[permissions] instead',
})
async workspaceRolePermissions(
@CurrentUser() user: CurrentUser,
@Args('id') id: string
): Promise<WorkspaceRolePermissions> {
const { role, permissions } = await this.ac
.user(user.id)
.workspace(id)
.permissions();
View on GitHub (pinned to 2af30773ae)