Significant-Gravitas/AutoGPT · error · ValueError

User {user_id} is not a member of the organization

Error message

User {user_id} is not a member of the organization

What it means

Raised by team_db.join_team when no OrgMember row exists for (org_id, user_id). Self-join requires org membership first — workspace membership is a subset of org membership in this data model. Plain ValueError from the DB layer.

Source

Thrown at autogpt_platform/backend/backend/api/features/orgs/team_db.py:112

    await prisma.team.delete(where={"id": ws_id})


async def join_team(ws_id: str, user_id: str, org_id: str) -> TeamResponse:
    """Self-join an OPEN workspace. User must be an org member."""
    ws = await prisma.team.find_unique(where={"id": ws_id})
    if ws is None:
        raise NotFoundError(f"Workspace {ws_id} not found")
    if ws.orgId != org_id:
        raise ValueError("Workspace does not belong to this organization")
    if ws.joinPolicy != "OPEN":
        raise ValueError("Cannot self-join a PRIVATE workspace. Request an invite.")

    # Verify user is actually an org member
    org_member = await prisma.orgmember.find_unique(
        where={"orgId_userId": {"orgId": org_id, "userId": user_id}}
    )
    if org_member is None:
        raise ValueError(f"User {user_id} is not a member of the organization")

    # Check not already a member
    existing = await prisma.teammember.find_unique(
        where={"teamId_userId": {"teamId": ws_id, "userId": user_id}}
    )
    if existing:
        return TeamResponse.from_db(ws)

    await prisma.teammember.create(
        data={
            "teamId": ws_id,
            "userId": user_id,
            "status": "ACTIVE",
        }
    )
    return TeamResponse.from_db(ws)

View on GitHub (pinned to 9c8bb5550f)

Solutions

  1. Have the user accept an org invitation or be added as an org member first (org member endpoints), then retry the workspace join
  2. Verify membership with the org-members API (GET org members) before exposing the join action
  3. If membership was recently revoked, refresh the user's org list and redirect them out of the removed org's UI
  4. In tests, create the OrgMember row in the fixture before calling join_team

Example fix

# before (test fixture)
await team_db.join_team(ws_id, user_id, org_id)  # raises: not an org member
# after
await prisma.orgmember.create(data={"orgId": org_id, "userId": user_id, "role": "MEMBER"})
await team_db.join_team(ws_id, user_id, org_id)
Defensive patterns

Strategy: validation

Validate before calling

const isMember = await isOrgMember(orgId, userId); // org members API
if (!isMember) throw new Error('Join the organization first');

Try / catch

try {
  await joinTeam(orgId, wsId);
} catch (e) {
  if (e.message.includes('not a member of the organization')) {
    // route user to org invitation flow
  } else throw e;
}

Prevention

When it happens

Trigger: POST /api/orgs/{org_id}/workspaces/{ws_id}/join where the authenticated user has not been added to the organization (no row in the OrgMember table for that pair). The route's ctx.org_id check may already block cross-org calls with 403, so this is mostly hit via direct DB-layer use, org membership revocation races, or the org_id path belonging to a workspace whose org the user never joined.

Common situations: User was removed from the org but still has an old session/UI state pointing at its workspaces; invitation to the org accepted but not yet propagated; tests calling team_db.join_team directly without creating the OrgMember fixture row.

Related errors


AI-assisted analysis of Significant-Gravitas/AutoGPT@9c8bb5550f (2026-08-14). Data as JSON: /api/errors/cf5bb68649aeee5c. Report an issue: GitHub.