Significant-Gravitas/AutoGPT · error · ValueError

Workspace {ws_id} does not belong to org {org_id}

Error message

Workspace {ws_id} does not belong to org {org_id}

What it means

Raised by team_db.add_team_member when the Team row for ws_id is missing OR its orgId differs from the passed org_id. One guard covering both conditions: the workspace must exist and belong to the organization you are adding within. Plain ValueError from the DB layer.

Source

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

        where={"teamId": ws_id, "status": "ACTIVE"},
        include={"User": True},
    )
    return [TeamMemberResponse.from_db(m) for m in members]


async def add_team_member(
    ws_id: str,
    user_id: str,
    org_id: str,
    is_admin: bool = False,
    is_billing_manager: bool = False,
    invited_by: str | None = None,
) -> TeamMemberResponse:
    """Add a member to a workspace. Must be an org member, workspace must belong to org."""
    # Verify workspace belongs to the org
    ws = await prisma.team.find_unique(where={"id": ws_id})
    if ws is None or ws.orgId != org_id:
        raise ValueError(f"Workspace {ws_id} does not belong to org {org_id}")

    # Verify user is in the org
    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")

    member = await prisma.teammember.create(
        data={
            "teamId": ws_id,
            "userId": user_id,
            "isAdmin": is_admin,
            "isBillingManager": is_billing_manager,
            "status": "ACTIVE",
            "invitedByUserId": invited_by,
        },
        include={"User": True},

View on GitHub (pinned to 9c8bb5550f)

Solutions

  1. Re-fetch the workspace through GET /api/orgs/{org_id}/workspaces/{ws_id} before showing the add-member form; failure means the pair is invalid
  2. Build the add-member URL from one TeamResponse (orgId + id) so the pair cannot diverge
  3. On failure, refresh the admin's workspace list — the workspace may have been deleted or moved
  4. In tests, create the workspace with create_team(org_id, ...) so orgId matches by construction

Example fix

// before
const url = `/api/orgs/${orgId}/workspaces/${selectedWsId}/members`;
// after
const ws = await getWorkspace(orgId, selectedWsId); // throws first if mismatch
const url = `/api/orgs/${ws.orgId}/workspaces/${ws.id}/members`;
Defensive patterns

Strategy: validation

Validate before calling

const ws = await getWorkspace(orgId, wsId).catch(() => null);
if (!ws || ws.orgId !== orgId) throw new Error('Invalid org/workspace pair');

Type guard

function workspaceInOrg(ws: TeamResponse, orgId: string): boolean {
  return ws.orgId === orgId;
}

Try / catch

try {
  await addTeamMember(orgId, wsId, userId);
} catch (e) {
  if (e.message.includes('does not belong to org')) {
    // refresh admin workspace picker; pair is stale
  } else throw e;
}

Prevention

When it happens

Trigger: POST /api/orgs/{org_id}/workspaces/{ws_id}/members where ws_id belongs to another org or does not exist. Note the condition is ws is None or ws.orgId != org_id — an already-deleted workspace produces the same 'does not belong' wording rather than a NotFoundError.

Common situations: Admin UI where the org dropdown and workspace picker hold unrelated selections; concurrent deletion of the workspace between list and submit; fixtures pairing a workspace from org A with org B's id.

Related errors


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