@@ -437,6 +437,60 @@ def update_handler(request: httpx.Request) -> httpx.Response:
437437 assert not hasattr (handle , "model_dump" )
438438
439439
440+ @respx .mock
441+ async def test_public_create_sandbox_serializes_image_without_runtime (
442+ mock_env_clear : None ,
443+ ) -> None :
444+ route = respx .post ("https://sandbox.test/v2/sandboxes" ).mock (
445+ return_value = httpx .Response (200 , json = _sandbox_response ())
446+ )
447+
448+ async with vercel .session (service_options = _session_options ()):
449+ await sandbox .create_sandbox (
450+ name = "preview" ,
451+ image = "acme/worker:latest" ,
452+ source = SnapshotSource (snapshot_id = "snap_123" ),
453+ )
454+
455+ body = json .loads (route .calls .last .request .content )
456+ assert body ["image" ] == "acme/worker:latest"
457+ assert body ["source" ] == {"type" : "snapshot" , "snapshotId" : "snap_123" }
458+ assert "runtime" not in body
459+
460+
461+ @respx .mock
462+ def test_sync_create_sandbox_serializes_image_without_runtime (mock_env_clear : None ) -> None :
463+ route = respx .post ("https://sandbox.test/v2/sandboxes" ).mock (
464+ return_value = httpx .Response (200 , json = _sandbox_response ())
465+ )
466+
467+ with vercel .session (service_options = _session_options ()):
468+ sandbox_sync .create_sandbox (name = "preview" , image = "acme/worker:latest" )
469+
470+ body = json .loads (route .calls .last .request .content )
471+ assert body ["image" ] == "acme/worker:latest"
472+ assert "runtime" not in body
473+
474+
475+ @respx .mock
476+ async def test_public_create_sandbox_rejects_runtime_and_image (
477+ mock_env_clear : None ,
478+ ) -> None :
479+ route = respx .post ("https://sandbox.test/v2/sandboxes" ).mock (
480+ return_value = httpx .Response (200 , json = _sandbox_response ())
481+ )
482+
483+ async with vercel .session (service_options = _session_options ()):
484+ with pytest .raises (ValidationError , match = "runtime and image" ):
485+ await sandbox .create_sandbox (
486+ name = "preview" ,
487+ runtime = "python3.13" ,
488+ image = "acme/worker:latest" ,
489+ )
490+
491+ assert not route .called
492+
493+
440494@respx .mock
441495async def test_network_policy_async_public_flow (mock_env_clear : None ) -> None :
442496 create_route = respx .post ("https://sandbox.test/v2/sandboxes" ).mock (
0 commit comments