langfuse/langfuse · error · TRPCError

FORBIDDEN

FORBIDDEN

Error message

You do not have the required access rights

What it means

Thrown by the RBAC allMembers tRPC route when both the organization access check and the project access check for scope 'projectMembers:read' fail. It is the member-list equivalent of the invites guard: read permission on members is required at org or project level.

Source

Thrown at web/src/features/rbac/server/allMembersRoutes.ts:227

    }),
  allFromProject: protectedProjectProcedure
    .input(projectLevelMemberQuery)
    .query(async ({ input, ctx }) => {
      const orgId = ctx.session.orgId;
      const orgAccess = hasOrganizationAccess({
        session: ctx.session,
        organizationId: orgId,
        scope: "organizationMembers:read",
      });

      const projectAccess = hasProjectAccess({
        session: ctx.session,
        projectId: input.projectId,
        scope: "projectMembers:read",
      });

      if (!orgAccess && !projectAccess) {
        throw new TRPCError({
          code: "FORBIDDEN",
          message: "You do not have the required access rights",
        });
      }

      return getMembers(
        ctx.prisma,
        {
          ...input,
          orgId,
        },
        orgAccess,
      );
    }),
};

View on GitHub (pinned to 59d92c7cf3)

Solutions

  1. Check the user's effective scopes for the target project (role definitions + project membership)
  2. Refresh the session / re-login after role or membership changes
  3. Ensure the UI only queries allMembers for projects the user currently belongs to
  4. Grant a role containing projectMembers:read if listing members is intended
Defensive patterns

Strategy: validation

Validate before calling

const allowed =
  hasProjectAccess({ session, projectId, scope: "projectMembers:read" }) ||
  hasOrganizationAccess({ session, organizationId: orgId, scope: "organizationMembers:read" });
if (!allowed) skipMembersQuery();

Try / catch

catch (e) { if (e.data?.code === "FORBIDDEN") { renderNoPermissionState(); } else throw e; }

Prevention

When it happens

Trigger: Calling allMembers with a projectId where the caller's roles lack projectMembers:read — e.g. a viewer-role user, or a user whose project membership was revoked but the UI still issues the query.

Common situations: Frontend pages (members table) loaded with a stale project switcher state, custom roles with read scopes accidentally removed, or session not yet reflecting a newly granted membership.

Related errors


AI-assisted analysis of langfuse/langfuse@59d92c7cf3 (2026-08-27). Data as JSON: /api/errors/d132296bd013011b. Report an issue: GitHub.