diff --git a/server.py b/server.py index 2d1f290..2377fd7 100644 --- a/server.py +++ b/server.py @@ -1784,9 +1784,11 @@ async def _register_asset_impl(req: RegisterRequest, owner: str): if not req.ipfs_cid: raise HTTPException(400, "IPFS CID is required for registration") - # Check if name exists - if await db.asset_exists(req.name): - raise HTTPException(400, f"Asset already exists: {req.name}") + # Check if name exists - return existing asset if so + existing = await db.get_asset_by_name(req.name) + if existing: + logger.info(f"register_asset: Asset {req.name} already exists, returning existing") + return {"asset": existing, "activity": None, "existing": True} # ===== PHASE 2: IPFS OPERATIONS (non-blocking) ===== import asyncio @@ -1805,7 +1807,10 @@ async def _register_asset_impl(req: RegisterRequest, owner: str): async with db.transaction() as conn: # Check name again inside transaction (race condition protection) if await db.asset_exists_by_name_tx(conn, req.name): - raise HTTPException(400, f"Asset already exists: {req.name}") + # Race condition - another request created it first, return existing + existing = await db.get_asset_by_name(req.name) + logger.info(f"register_asset: Asset {req.name} created by concurrent request") + return {"asset": existing, "activity": None, "existing": True} # Create asset asset = { @@ -2084,9 +2089,11 @@ async def record_run(req: RecordRunRequest, user: User = Depends(get_required_us } await db.create_asset_tx(conn, input_asset) - # Check output doesn't already exist (by content_hash) + # Check if output already exists (by content_hash) - return existing if so if await db.asset_exists_by_name_tx(conn, output_hash): - raise HTTPException(400, f"Asset already exists: {output_hash[:16]}...") + existing = await db.get_asset_by_name(output_hash) + logger.info(f"record_run: Output {output_hash[:16]}... already exists") + return {"asset": existing, "activity": None, "existing": True} # Create output asset with provenance - named by content_hash output_asset = {