From 4f695d7e622adbea3f93c0150e3cd8b8f5028993 Mon Sep 17 00:00:00 2001 From: Fusion Date: Tue, 19 May 2026 22:55:47 +0200 Subject: [PATCH] fix: accept tool instance creation params in request body The create_instance endpoint was expecting tool_type_id and display_name as query parameters, but the frontend sends them in the JSON body. Added CreateInstanceRequest Pydantic model to properly parse the request body. Fixes 422 Unprocessable Content error on instance creation. --- apps/api/src/api/tool_instances.py | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/apps/api/src/api/tool_instances.py b/apps/api/src/api/tool_instances.py index e17d42f..1d5f9ba 100644 --- a/apps/api/src/api/tool_instances.py +++ b/apps/api/src/api/tool_instances.py @@ -5,6 +5,7 @@ import uuid from datetime import datetime from fastapi import APIRouter, Depends, HTTPException, status +from pydantic import BaseModel, Field from sqlalchemy import select from sqlalchemy.ext.asyncio import AsyncSession @@ -29,6 +30,13 @@ from src.services.docker import ( router = APIRouter(prefix="/projects", tags=["tool-instances"]) +class CreateInstanceRequest(BaseModel): + """Request body for creating a tool instance.""" + + tool_type_id: str = Field(description="UUID of the tool type to instantiate") + display_name: str | None = Field(default=None, description="Optional display name for the instance") + + async def _get_user(session: AsyncSession, user_id: uuid.UUID) -> User: """Fetch a user by ID or raise 404 if not found.""" user = await session.get(User, user_id) @@ -71,8 +79,7 @@ async def _get_owned_project( async def create_instance( project_id: uuid.UUID, repo_id: uuid.UUID, - tool_type_id: uuid.UUID, - display_name: str | None = None, + data: CreateInstanceRequest, user_id: uuid.UUID = Depends(get_current_user_id), session: AsyncSession = Depends(get_db_session), ) -> dict: @@ -98,6 +105,7 @@ async def create_instance( status_code=status.HTTP_404_NOT_FOUND, detail="repository not found" ) + tool_type_id = uuid.UUID(data.tool_type_id) tool_type = await session.get(ToolType, tool_type_id) if tool_type is None: raise HTTPException( @@ -106,7 +114,7 @@ async def create_instance( # Generate unique name instance_name = f"{tool_type.name}-{repo.name}-{uuid.uuid4().hex[:8]}" - instance_display = display_name or f"{tool_type.display_name} - {repo.name}" + instance_display = data.display_name or f"{tool_type.display_name} - {repo.name}" # Create instance directory instance_dir = ensure_instance_directory(instance_name)