diff --git a/backend/app/api/agent.py b/backend/app/api/agent.py index fdfaf4a8..ea54af3c 100644 --- a/backend/app/api/agent.py +++ b/backend/app/api/agent.py @@ -783,7 +783,7 @@ async def delete_task( _guard_task_access(agent_ctx, task) _require_board_lead(agent_ctx) if task.board_id is None: - raise HTTPException(status_code=status.HTTP_422_UNPROCESSABLE_ENTITY) + raise HTTPException(status_code=status.HTTP_422_UNPROCESSABLE_CONTENT) await tasks_api.delete_task_and_related_records(session, task=task) return OkResponse() diff --git a/backend/app/api/board_group_memory.py b/backend/app/api/board_group_memory.py index f59b5ff3..d965c718 100644 --- a/backend/app/api/board_group_memory.py +++ b/backend/app/api/board_group_memory.py @@ -600,7 +600,7 @@ async def create_board_group_memory_for_board( group_id = board.board_group_id if group_id is None: raise HTTPException( - status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, + status_code=status.HTTP_422_UNPROCESSABLE_CONTENT, detail="Board is not in a board group", ) group = await BoardGroup.objects.by_id(group_id).first(session) diff --git a/backend/app/api/board_groups.py b/backend/app/api/board_groups.py index 1d9808d3..d718d777 100644 --- a/backend/app/api/board_groups.py +++ b/backend/app/api/board_groups.py @@ -160,7 +160,7 @@ async def get_board_group_snapshot( write=False, ) if per_board_task_limit < 0: - raise HTTPException(status_code=status.HTTP_422_UNPROCESSABLE_ENTITY) + raise HTTPException(status_code=status.HTTP_422_UNPROCESSABLE_CONTENT) snapshot = await build_group_snapshot( session, group=group, diff --git a/backend/app/api/board_webhooks.py b/backend/app/api/board_webhooks.py index e0107a2c..788607ea 100644 --- a/backend/app/api/board_webhooks.py +++ b/backend/app/api/board_webhooks.py @@ -262,7 +262,7 @@ async def _validate_agent_id( agent = await Agent.objects.filter_by(id=agent_id, board_id=board.id).first(session) if agent is None: raise HTTPException( - status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, + status_code=status.HTTP_422_UNPROCESSABLE_CONTENT, detail="agent_id must reference an agent on this board.", ) diff --git a/backend/app/api/boards.py b/backend/app/api/boards.py index 4c33ddf9..ea7ebff9 100644 --- a/backend/app/api/boards.py +++ b/backend/app/api/boards.py @@ -69,12 +69,12 @@ async def _require_gateway( gateway = await crud.get_by_id(session, Gateway, gateway_id) if gateway is None: raise HTTPException( - status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, + status_code=status.HTTP_422_UNPROCESSABLE_CONTENT, detail="gateway_id is invalid", ) if organization_id is not None and gateway.organization_id != organization_id: raise HTTPException( - status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, + status_code=status.HTTP_422_UNPROCESSABLE_CONTENT, detail="gateway_id is invalid", ) return gateway @@ -101,12 +101,12 @@ async def _require_board_group( group = await crud.get_by_id(session, BoardGroup, board_group_id) if group is None: raise HTTPException( - status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, + status_code=status.HTTP_422_UNPROCESSABLE_CONTENT, detail="board_group_id is invalid", ) if organization_id is not None and group.organization_id != organization_id: raise HTTPException( - status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, + status_code=status.HTTP_422_UNPROCESSABLE_CONTENT, detail="board_group_id is invalid", ) return group @@ -153,12 +153,12 @@ async def _apply_board_update( if updates.get("board_type") == "goal" and (not board.objective or not board.success_metrics): # Validate only when explicitly switching to goal boards. raise HTTPException( - status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, + status_code=status.HTTP_422_UNPROCESSABLE_CONTENT, detail="Goal boards require objective and success_metrics", ) if not board.gateway_id: raise HTTPException( - status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, + status_code=status.HTTP_422_UNPROCESSABLE_CONTENT, detail="gateway_id is required", ) board.updated_at = utcnow() diff --git a/backend/app/api/organizations.py b/backend/app/api/organizations.py index 683e7996..c776c655 100644 --- a/backend/app/api/organizations.py +++ b/backend/app/api/organizations.py @@ -127,7 +127,7 @@ async def create_organization( raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED) name = payload.name.strip() if not name: - raise HTTPException(status_code=status.HTTP_422_UNPROCESSABLE_ENTITY) + raise HTTPException(status_code=status.HTTP_422_UNPROCESSABLE_CONTENT) existing = ( await session.exec( select(Organization).where( @@ -513,7 +513,7 @@ async def update_member_access( .all(session) } if valid_board_ids != board_ids: - raise HTTPException(status_code=status.HTTP_422_UNPROCESSABLE_ENTITY) + raise HTTPException(status_code=status.HTTP_422_UNPROCESSABLE_CONTENT) await apply_member_access_update(session, member=member, update=payload) await session.commit() @@ -614,7 +614,7 @@ async def create_org_invite( """Create an organization invite for an email address.""" email = normalize_invited_email(payload.invited_email) if not email: - raise HTTPException(status_code=status.HTTP_422_UNPROCESSABLE_ENTITY) + raise HTTPException(status_code=status.HTTP_422_UNPROCESSABLE_CONTENT) existing_user = ( await session.exec(select(User).where(func.lower(col(User.email)) == email)) @@ -654,7 +654,7 @@ async def create_org_invite( .all(session) } if valid_board_ids != board_ids: - raise HTTPException(status_code=status.HTTP_422_UNPROCESSABLE_ENTITY) + raise HTTPException(status_code=status.HTTP_422_UNPROCESSABLE_CONTENT) await apply_invite_board_access( session, invite=invite, diff --git a/backend/app/api/souls_directory.py b/backend/app/api/souls_directory.py index 92427d78..69afe1fa 100644 --- a/backend/app/api/souls_directory.py +++ b/backend/app/api/souls_directory.py @@ -25,7 +25,7 @@ def _validate_segment(value: str, *, field: str) -> str: cleaned = value.strip().strip("/") if not cleaned: raise HTTPException( - status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, + status_code=status.HTTP_422_UNPROCESSABLE_CONTENT, detail=f"{field} is required", ) if field == "handle": @@ -34,7 +34,7 @@ def _validate_segment(value: str, *, field: str) -> str: ok = bool(_SAFE_SLUG_RE.match(cleaned)) if not ok: raise HTTPException( - status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, + status_code=status.HTTP_422_UNPROCESSABLE_CONTENT, detail=f"{field} contains unsupported characters", ) return cleaned diff --git a/backend/app/api/task_custom_fields.py b/backend/app/api/task_custom_fields.py index cd82f33e..904710d3 100644 --- a/backend/app/api/task_custom_fields.py +++ b/backend/app/api/task_custom_fields.py @@ -84,7 +84,7 @@ async def _validated_board_ids_for_org( normalized_board_ids = list(dict.fromkeys(board_ids)) if not normalized_board_ids: raise HTTPException( - status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, + status_code=status.HTTP_422_UNPROCESSABLE_CONTENT, detail="At least one board must be selected.", ) valid_board_ids = set( @@ -103,7 +103,7 @@ async def _validated_board_ids_for_org( ) if missing_board_ids: raise HTTPException( - status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, + status_code=status.HTTP_422_UNPROCESSABLE_CONTENT, detail={ "message": "Some selected boards are invalid for this organization.", "invalid_board_ids": [str(value) for value in missing_board_ids], @@ -177,7 +177,7 @@ async def create_org_custom_field( ) except ValueError as err: raise HTTPException( - status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, + status_code=status.HTTP_422_UNPROCESSABLE_CONTENT, detail=str(err), ) from err definition = TaskCustomFieldDefinition( @@ -252,7 +252,7 @@ async def update_org_custom_field( ) except ValueError as err: raise HTTPException( - status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, + status_code=status.HTTP_422_UNPROCESSABLE_CONTENT, detail=str(err), ) from err for key, value in updates.items(): diff --git a/backend/app/api/tasks.py b/backend/app/api/tasks.py index d5132814..ae1bf981 100644 --- a/backend/app/api/tasks.py +++ b/backend/app/api/tasks.py @@ -121,7 +121,7 @@ class _BoardCustomFieldDefinition: def _comment_validation_error() -> HTTPException: return HTTPException( - status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, + status_code=status.HTTP_422_UNPROCESSABLE_CONTENT, detail="Comment is required.", ) @@ -723,7 +723,7 @@ def _status_values(status_filter: str | None) -> list[str]: values = [s.strip() for s in status_filter.split(",") if s.strip()] if any(value not in ALLOWED_STATUSES for value in values): raise HTTPException( - status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, + status_code=status.HTTP_422_UNPROCESSABLE_CONTENT, detail="Unsupported task status filter.", ) return values @@ -777,7 +777,7 @@ def _reject_unknown_custom_field_keys( if not unknown_field_keys: return raise HTTPException( - status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, + status_code=status.HTTP_422_UNPROCESSABLE_CONTENT, detail={ "message": "Unknown custom field keys for this board.", "unknown_field_keys": unknown_field_keys, @@ -798,7 +798,7 @@ def _reject_missing_required_custom_field_keys( if not missing_field_keys: return raise HTTPException( - status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, + status_code=status.HTTP_422_UNPROCESSABLE_CONTENT, detail={ "message": "Required custom fields must have values.", "missing_field_keys": sorted(missing_field_keys), @@ -821,7 +821,7 @@ def _reject_invalid_custom_field_values( ) except ValueError as err: raise HTTPException( - status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, + status_code=status.HTTP_422_UNPROCESSABLE_CONTENT, detail={ "message": "Invalid custom field value.", "field_key": field_key, @@ -1372,7 +1372,7 @@ async def update_task( """Update task status, assignment, comment, and dependency state.""" if task.board_id is None: raise HTTPException( - status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, + status_code=status.HTTP_422_UNPROCESSABLE_CONTENT, detail="Task board_id is required.", ) board_id = task.board_id @@ -1498,7 +1498,7 @@ async def delete_task( ) -> OkResponse: """Delete a task and related records.""" if task.board_id is None: - raise HTTPException(status_code=status.HTTP_422_UNPROCESSABLE_ENTITY) + raise HTTPException(status_code=status.HTTP_422_UNPROCESSABLE_CONTENT) board = await Board.objects.by_id(task.board_id).first(session) if board is None: raise HTTPException(status_code=status.HTTP_404_NOT_FOUND) @@ -1534,7 +1534,7 @@ async def _validate_task_comment_access( actor: ActorContext, ) -> None: if task.board_id is None: - raise HTTPException(status_code=status.HTTP_422_UNPROCESSABLE_ENTITY) + raise HTTPException(status_code=status.HTTP_422_UNPROCESSABLE_CONTENT) if actor.actor_type == "user" and actor.user is not None: board = await Board.objects.by_id(task.board_id).first(session) @@ -1677,13 +1677,13 @@ class _TaskUpdateInput: def _required_status_value(value: object) -> str: if isinstance(value, str): return value - raise HTTPException(status_code=status.HTTP_422_UNPROCESSABLE_ENTITY) + raise HTTPException(status_code=status.HTTP_422_UNPROCESSABLE_CONTENT) def _optional_assigned_agent_id(value: object) -> UUID | None: if value is None or isinstance(value, UUID): return value - raise HTTPException(status_code=status.HTTP_422_UNPROCESSABLE_ENTITY) + raise HTTPException(status_code=status.HTTP_422_UNPROCESSABLE_CONTENT) async def _board_organization_id( diff --git a/backend/app/services/openclaw/admin_service.py b/backend/app/services/openclaw/admin_service.py index 1c25aaa8..11d63cb7 100644 --- a/backend/app/services/openclaw/admin_service.py +++ b/backend/app/services/openclaw/admin_service.py @@ -208,7 +208,7 @@ class GatewayAdminLifecycleService(OpenClawDBService): ) if template_user is None: raise HTTPException( - status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, + status_code=status.HTTP_422_UNPROCESSABLE_CONTENT, detail="Organization owner not found (required for gateway agent USER.md rendering).", ) raw_token = mint_agent_token(agent) diff --git a/backend/app/services/openclaw/coordination_service.py b/backend/app/services/openclaw/coordination_service.py index 12c2a44e..8c9817c5 100644 --- a/backend/app/services/openclaw/coordination_service.py +++ b/backend/app/services/openclaw/coordination_service.py @@ -184,7 +184,7 @@ class GatewayCoordinationService(AbstractGatewayMessagingService): target = await self._board_agent_or_404(board=board, agent_id=target_agent_id) if not target.openclaw_session_id: raise HTTPException( - status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, + status_code=status.HTTP_422_UNPROCESSABLE_CONTENT, detail="Target agent has no session key", ) _gateway, config = await GatewayDispatchService( @@ -335,7 +335,7 @@ class GatewayCoordinationService(AbstractGatewayMessagingService): normalized_content = content.strip() if not normalized_content: raise HTTPException( - status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, + status_code=status.HTTP_422_UNPROCESSABLE_CONTENT, detail="content is required", ) @@ -541,7 +541,7 @@ class GatewayCoordinationService(AbstractGatewayMessagingService): ) if not lead.openclaw_session_id: raise HTTPException( - status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, + status_code=status.HTTP_422_UNPROCESSABLE_CONTENT, detail="Lead agent has no session key", ) await self._dispatch_gateway_message( diff --git a/backend/app/services/openclaw/gateway_resolver.py b/backend/app/services/openclaw/gateway_resolver.py index 4f6db691..7e31814f 100644 --- a/backend/app/services/openclaw/gateway_resolver.py +++ b/backend/app/services/openclaw/gateway_resolver.py @@ -28,7 +28,7 @@ def gateway_client_config(gateway: Gateway) -> GatewayClientConfig: url = (gateway.url or "").strip() if not url: raise HTTPException( - status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, + status_code=status.HTTP_422_UNPROCESSABLE_CONTENT, detail="Gateway url is required", ) token = (gateway.token or "").strip() or None @@ -51,7 +51,7 @@ def require_gateway_workspace_root(gateway: Gateway) -> str: workspace_root = (gateway.workspace_root or "").strip() if not workspace_root: raise HTTPException( - status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, + status_code=status.HTTP_422_UNPROCESSABLE_CONTENT, detail="Gateway workspace_root is required", ) return workspace_root @@ -82,13 +82,13 @@ async def require_gateway_for_board( """Return a board's gateway or raise a 422 with a stable error message.""" if board.gateway_id is None: raise HTTPException( - status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, + status_code=status.HTTP_422_UNPROCESSABLE_CONTENT, detail="Board gateway_id is required", ) gateway = await get_gateway_for_board(session, board) if gateway is None: raise HTTPException( - status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, + status_code=status.HTTP_422_UNPROCESSABLE_CONTENT, detail="Board gateway_id is invalid", ) if require_workspace_root: diff --git a/backend/app/services/openclaw/policies.py b/backend/app/services/openclaw/policies.py index 556abf4c..8bca6cb7 100644 --- a/backend/app/services/openclaw/policies.py +++ b/backend/app/services/openclaw/policies.py @@ -63,7 +63,7 @@ class OpenClawAuthorizationPolicy: def require_gateway_configured(gateway: Gateway) -> None: if not gateway.url: raise HTTPException( - status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, + status_code=status.HTTP_422_UNPROCESSABLE_CONTENT, detail="Gateway url is required", ) diff --git a/backend/app/services/openclaw/provisioning_db.py b/backend/app/services/openclaw/provisioning_db.py index 7ed003cd..6618b64c 100644 --- a/backend/app/services/openclaw/provisioning_db.py +++ b/backend/app/services/openclaw/provisioning_db.py @@ -755,7 +755,7 @@ class AgentLifecycleService(OpenClawDBService): if existing: return existing raise HTTPException( - status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, + status_code=status.HTTP_422_UNPROCESSABLE_CONTENT, detail="Gateway main agent session key is required", ) if agent.is_board_lead: @@ -766,7 +766,7 @@ class AgentLifecycleService(OpenClawDBService): def workspace_path(cls, agent_name: str, workspace_root: str | None) -> str: if not workspace_root: raise HTTPException( - status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, + status_code=status.HTTP_422_UNPROCESSABLE_CONTENT, detail="Gateway workspace_root is required", ) root = workspace_root.rstrip("/") @@ -781,7 +781,7 @@ class AgentLifecycleService(OpenClawDBService): ) -> Board: if not board_id: raise HTTPException( - status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, + status_code=status.HTTP_422_UNPROCESSABLE_CONTENT, detail="board_id is required", ) board = await Board.objects.by_id(board_id).first(self.session) @@ -1070,7 +1070,7 @@ class AgentLifecycleService(OpenClawDBService): ) if template_user is None: raise HTTPException( - status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, + status_code=status.HTTP_422_UNPROCESSABLE_CONTENT, detail=( "User context is required to provision the gateway main agent " "(org owner not found)." @@ -1220,7 +1220,7 @@ class AgentLifecycleService(OpenClawDBService): elif make_main is not None: if "board_id" not in updates or updates["board_id"] is None: raise HTTPException( - status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, + status_code=status.HTTP_422_UNPROCESSABLE_CONTENT, detail=( "board_id is required when converting a gateway-main agent " "to board scope" @@ -1229,7 +1229,7 @@ class AgentLifecycleService(OpenClawDBService): board = await self.require_board(updates["board_id"]) if board.gateway_id is None: raise HTTPException( - status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, + status_code=status.HTTP_422_UNPROCESSABLE_CONTENT, detail="Board gateway_id is required", ) updates["gateway_id"] = board.gateway_id @@ -1239,7 +1239,7 @@ class AgentLifecycleService(OpenClawDBService): board = await self.require_board(updates["board_id"]) if board.gateway_id is None: raise HTTPException( - status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, + status_code=status.HTTP_422_UNPROCESSABLE_CONTENT, detail="Board gateway_id is required", ) updates["gateway_id"] = board.gateway_id @@ -1254,7 +1254,7 @@ class AgentLifecycleService(OpenClawDBService): board = await self.require_board(agent.board_id) if board.gateway_id is None: raise HTTPException( - status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, + status_code=status.HTTP_422_UNPROCESSABLE_CONTENT, detail="Board gateway_id is required", ) agent.gateway_id = board.gateway_id @@ -1277,7 +1277,7 @@ class AgentLifecycleService(OpenClawDBService): if make_main: if gateway_for_main is None: raise HTTPException( - status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, + status_code=status.HTTP_422_UNPROCESSABLE_CONTENT, detail="Gateway agent requires a gateway configuration", ) return AgentUpdateProvisionTarget( @@ -1295,7 +1295,7 @@ class AgentLifecycleService(OpenClawDBService): if agent.board_id is None: raise HTTPException( - status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, + status_code=status.HTTP_422_UNPROCESSABLE_CONTENT, detail="board_id is required for non-main agents", ) board = await self.require_board(agent.board_id) diff --git a/backend/app/services/openclaw/session_service.py b/backend/app/services/openclaw/session_service.py index 1be1dd28..c42d707a 100644 --- a/backend/app/services/openclaw/session_service.py +++ b/backend/app/services/openclaw/session_service.py @@ -101,7 +101,7 @@ class GatewaySessionService(OpenClawDBService): raw_url = params.gateway_url.strip() if not raw_url: raise HTTPException( - status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, + status_code=status.HTTP_422_UNPROCESSABLE_CONTENT, detail="board_id or gateway_url is required", ) return ( @@ -114,7 +114,7 @@ class GatewaySessionService(OpenClawDBService): ) if not params.board_id: raise HTTPException( - status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, + status_code=status.HTTP_422_UNPROCESSABLE_CONTENT, detail="board_id or gateway_url is required", ) board = await Board.objects.by_id(params.board_id).first(self.session) @@ -144,7 +144,7 @@ class GatewaySessionService(OpenClawDBService): board, config, main_session = await self.resolve_gateway(params, user=user) if board is None: raise HTTPException( - status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, + status_code=status.HTTP_422_UNPROCESSABLE_CONTENT, detail="board_id is required", ) return board, config, main_session