fix: update HTTP status code from UNPROCESSABLE_ENTITY to UNPROCESSABLE_CONTENT

This commit is contained in:
Abhimanyu Saharan
2026-02-15 16:06:06 +05:30
parent 24731667d4
commit b702ade0cc
15 changed files with 52 additions and 52 deletions

View File

@@ -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()

View File

@@ -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)

View File

@@ -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,

View File

@@ -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.",
)

View File

@@ -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()

View File

@@ -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,

View File

@@ -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

View File

@@ -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():

View File

@@ -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(

View File

@@ -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)

View File

@@ -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(

View File

@@ -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:

View File

@@ -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",
)

View File

@@ -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)

View File

@@ -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