{"record":{"id":"e89cbabaa36c111c","repo":"toeverything/AFFiNE","slug":"space-access-denied-e89cba","errorCode":"space_access_denied","errorMessage":"You do not have permission to access Space ${spaceId}.","messagePattern":"You do not have permission to access Space (.+?)\\.","errorType":"http","errorClass":"SpaceAccessDenied","httpStatus":403,"severity":"error","filePath":"packages/backend/server/src/core/workspaces/resolvers/workspace.ts","lineNumber":196,"sourceCode":"\n    return workspace;\n  }\n\n  @Query(() => WorkspaceRolePermissions, {\n    description: 'Get workspace role permissions',\n    deprecationReason: 'use WorkspaceType[permissions] instead',\n  })\n  async workspaceRolePermissions(\n    @CurrentUser() user: CurrentUser,\n    @Args('id') id: string\n  ): Promise<WorkspaceRolePermissions> {\n    const { role, permissions } = await this.ac\n      .user(user.id)\n      .workspace(id)\n      .permissions();\n\n    if (!role) {\n      throw new SpaceAccessDenied({ spaceId: id });\n    }\n\n    return {\n      role,\n      permissions: mapPermissionsToGraphqlPermissions(permissions),\n    };\n  }\n\n  @Mutation(() => WorkspaceType, {\n    description: 'Create a new workspace',\n  })\n  async createWorkspace(\n    @CurrentUser() user: CurrentUser,\n    // we no longer support init workspace with a preload file\n    // use sync system to uploading them once created\n    @Args({ name: 'init', type: () => GraphQLUpload, nullable: true })\n    init: FileUpload | null\n  ) {","sourceCodeStart":178,"sourceCodeEnd":214,"githubUrl":"https://github.com/toeverything/AFFiNE/blob/26c515e050211269e911f7d9cfe162a26c83ed98/packages/backend/server/src/core/workspaces/resolvers/workspace.ts#L178-L214","documentation":"Thrown by the deprecated `workspaceRolePermissions` query when `ac.user(user.id).workspace(id).permissions()` returns no role for the caller — i.e. the user has no membership or role assignment in that workspace. Coded `space_access_denied` (no_permission) with `{ spaceId }`.","triggerScenarios":"Calling `workspaceRolePermissions(workspaceId)` as a user who is not a member of the workspace — no role row in `workspace_user`, no inherited permission. Also fires after a user is removed but their client still issues the query.","commonSituations":"User removed from the workspace but the page still mounted; a shared URL opened by an outsider; permission system hasn't yet propagated a freshly-revoked role; querying a workspace the user was never invited to.","solutions":["Confirm the user is still a member of the workspace before querying role permissions.","Prefer the non-deprecated `WorkspaceType[permissions]` field noted in the deprecation reason.","Handle `space_access_denied` by redirecting to the workspace list or a 'no access' page.","Refresh the session/membership cache if the role was just granted and is not yet visible."],"exampleFix":"// before\nconst { role, permissions } = await sdk.workspaceRolePermissions({ id });\n\n// after\nconst ws = await sdk.workspace({ id }); // WorkspaceType.permissions is the replacement\nconst permissions = ws.permissions;\n\n// guard:\ntry { ... } catch (e) {\n  if (e.code === 'space_access_denied') router.push('/workspaces');\n}","handlingStrategy":"validation","validationCode":"// Prefer the non-deprecated path and confirm membership\nif (!myWorkspaces.find(w => w.id === workspaceId)) {\n  router.push('/workspaces');\n  return;\n}\nconst ws = await sdk.workspace({ id: workspaceId });\nconst permissions = ws.permissions;","typeGuard":"function hasWorkspaceAccess(workspaceId, myWorkspaces) {\n  return myWorkspaces.some(w => w.id === workspaceId);\n}","tryCatchPattern":"try {\n  const { role, permissions } = await sdk.workspaceRolePermissions({ id });\n} catch (e) {\n  if (e.code === 'space_access_denied') {\n    router.push('/workspaces');\n  } else throw e;\n}","preventionTips":["Migrate off the deprecated query to WorkspaceType.permissions.","Confirm membership before querying role permissions.","Handle space_access_denied by redirecting to the workspace list."],"tags":["graphql","workspace","authorization","deprecated","nestjs"],"backgroundTag":null,"analyzedSha":"26c515e050211269e911f7d9cfe162a26c83ed98","analyzedAt":"2026-08-12T13:15:16.447Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}