{"record":{"id":"b20e1714c13def8f","repo":"Significant-Gravitas/AutoGPT","slug":"cannot-change-the-default-workspace-s-join-policy","errorCode":null,"errorMessage":"Cannot change the default workspace's join policy","messagePattern":"Cannot change the default workspace's join policy","errorType":"http","errorClass":"ValueError","httpStatus":400,"severity":"error","filePath":"autogpt_platform/backend/backend/api/features/orgs/team_db.py","lineNumber":80,"sourceCode":"    ws = await prisma.team.find_unique(where={\"id\": ws_id})\n    if ws is None:\n        raise NotFoundError(f\"Workspace {ws_id} not found\")\n    if expected_org_id and ws.orgId != expected_org_id:\n        raise NotFoundError(f\"Workspace {ws_id} not found in org {expected_org_id}\")\n    return TeamResponse.from_db(ws)\n\n\nasync def update_team(ws_id: str, data: dict) -> TeamResponse:\n    \"\"\"Update workspace fields. Guards the default workspace join policy.\"\"\"\n    update_data = {k: v for k, v in data.items() if v is not None}\n    if not update_data:\n        return await get_team(ws_id)\n\n    # Guard: default workspace joinPolicy cannot be changed\n    if \"joinPolicy\" in update_data:\n        ws = await prisma.team.find_unique(where={\"id\": ws_id})\n        if ws and ws.isDefault:\n            raise ValueError(\"Cannot change the default workspace's join policy\")\n\n    await prisma.team.update(where={\"id\": ws_id}, data=update_data)\n    return await get_team(ws_id)\n\n\nasync def delete_team(ws_id: str) -> None:\n    \"\"\"Delete a workspace. Cannot delete the default workspace.\"\"\"\n    ws = await prisma.team.find_unique(where={\"id\": ws_id})\n    if ws is None:\n        raise NotFoundError(f\"Workspace {ws_id} not found\")\n    if ws.isDefault:\n        raise ValueError(\"Cannot delete the default workspace\")\n\n    await prisma.team.delete(where={\"id\": ws_id})\n\n\nasync def join_team(ws_id: str, user_id: str, org_id: str) -> TeamResponse:\n    \"\"\"Self-join an OPEN workspace. User must be an org member.\"\"\"","sourceCodeStart":62,"sourceCodeEnd":98,"githubUrl":"https://github.com/Significant-Gravitas/AutoGPT/blob/9c8bb5550f446ba5d3046b78896578742495b3cf/autogpt_platform/backend/backend/api/features/orgs/team_db.py#L62-L98","documentation":"Raised by team_db.update_team when a PATCH workspace request includes a 'joinPolicy' field and the target workspace has isDefault=true. Every org has one default workspace that all org members must be able to join, so its join policy is immutable. It is a plain ValueError raised at the DB layer; over HTTP the route (update_team in team_routes.py) surfaces it as a 400/500 depending on the app's exception mapping.","triggerScenarios":"PATCH /api/orgs/{org_id}/workspaces/{ws_id} with a body containing join_policy (e.g. {\"join_policy\": \"PRIVATE\"}) where ws_id is the org's default workspace. Only fires when joinPolicy is a non-None key in the update dict; omitting the field or sending null skips the guard.","commonSituations":"Frontend settings form that always submits the full workspace object (including joinPolicy) even when the user only edited name/description; admin tooling that copies a non-default workspace's payload onto the default workspace; tests that reuse one fixture payload for all workspaces.","solutions":["Send only the fields you intend to change — omit join_policy entirely when PATCHing the default workspace","If the UI must show the control, disable it for workspaces where isDefault is true (TeamResponse exposes it)","Switch the join policy on a non-default workspace, or create a new workspace with the desired policy instead","If you genuinely need the default workspace open/closed org-wide, change the org's membership rules, not the workspace joinPolicy"],"exampleFix":"// before\nawait sdk.patchWorkspace(orgId, wsId, {\n  name: newName,\n  joinPolicy: currentJoinPolicy, // always sent -> 400 on default ws\n});\n// after\nawait sdk.patchWorkspace(orgId, wsId, { name: newName });","handlingStrategy":"validation","validationCode":"const ws = await getWorkspace(orgId, wsId);\nif (ws.isDefault && 'joinPolicy' in patch) {\n  throw new Error('Default workspace join policy is immutable');\n}","typeGuard":"function isDefaultWorkspace(ws: TeamResponse): boolean {\n  return ws.isDefault === true;\n}","tryCatchPattern":"try {\n  await patchWorkspace(orgId, wsId, patch);\n} catch (e) {\n  if (e instanceof Error && e.message.includes(\"default workspace's join policy\")) {\n    // strip joinPolicy and retry with editable fields only\n    const { joinPolicy, ...rest } = patch;\n    await patchWorkspace(orgId, wsId, rest);\n  } else throw e;\n}","preventionTips":["Send partial PATCH bodies containing only changed fields","Disable policy controls in UI for isDefault workspaces","Never copy a workspace payload wholesale onto the default workspace"],"tags":["workspaces","orgs","validation","valueerror"],"backgroundTag":null,"analyzedSha":"9c8bb5550f446ba5d3046b78896578742495b3cf","analyzedAt":"2026-08-14T17:17:21.957Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}