diff --git a/skyvern-frontend/src/components/GeoTargetSelector.tsx b/skyvern-frontend/src/components/GeoTargetSelector.tsx index 24030f5f..9dc695ba 100644 --- a/skyvern-frontend/src/components/GeoTargetSelector.tsx +++ b/skyvern-frontend/src/components/GeoTargetSelector.tsx @@ -124,7 +124,7 @@ export function GeoTargetSelector({ {results.countries.map((item) => ( handleSelect(item)} > diff --git a/skyvern-frontend/src/routes/workflows/components/WorkflowVisualComparisonDrawer.tsx b/skyvern-frontend/src/routes/workflows/components/WorkflowVisualComparisonDrawer.tsx index f9fd7aca..3d975983 100644 --- a/skyvern-frontend/src/routes/workflows/components/WorkflowVisualComparisonDrawer.tsx +++ b/skyvern-frontend/src/routes/workflows/components/WorkflowVisualComparisonDrawer.tsx @@ -116,7 +116,7 @@ function compareWorkflowBlocks( function getWorkflowElements(version: WorkflowVersion) { const settings: WorkflowSettings = { - proxyLocation: version.proxy_location || ProxyLocation.Residential, + proxyLocation: version.proxy_location ?? ProxyLocation.Residential, webhookCallbackUrl: version.webhook_callback_url || "", persistBrowserSession: version.persist_browser_session, model: version.model, diff --git a/skyvern-frontend/src/routes/workflows/editor/Workspace.tsx b/skyvern-frontend/src/routes/workflows/editor/Workspace.tsx index 74682295..c3e636dd 100644 --- a/skyvern-frontend/src/routes/workflows/editor/Workspace.tsx +++ b/skyvern-frontend/src/routes/workflows/editor/Workspace.tsx @@ -956,7 +956,7 @@ function Workspace({ // Load the selected version into the main editor const settings: WorkflowSettings = { proxyLocation: - selectedVersion.proxy_location || ProxyLocation.Residential, + selectedVersion.proxy_location ?? ProxyLocation.Residential, webhookCallbackUrl: selectedVersion.webhook_callback_url || "", persistBrowserSession: selectedVersion.persist_browser_session, model: selectedVersion.model, @@ -1660,7 +1660,7 @@ function Workspace({ const settings: WorkflowSettings = { proxyLocation: - saveData?.settings.proxyLocation || ProxyLocation.Residential, + saveData?.settings.proxyLocation ?? ProxyLocation.Residential, webhookCallbackUrl: saveData?.settings.webhookCallbackUrl || "", persistBrowserSession: saveData?.settings.persistBrowserSession ?? false, diff --git a/skyvern-frontend/src/routes/workflows/editor/panels/WorkflowComparisonPanel.tsx b/skyvern-frontend/src/routes/workflows/editor/panels/WorkflowComparisonPanel.tsx index 6675f812..eff44658 100644 --- a/skyvern-frontend/src/routes/workflows/editor/panels/WorkflowComparisonPanel.tsx +++ b/skyvern-frontend/src/routes/workflows/editor/panels/WorkflowComparisonPanel.tsx @@ -141,7 +141,7 @@ function compareWorkflowBlocks( function getWorkflowElements(version: WorkflowVersion) { const settings: WorkflowSettings = { - proxyLocation: version.proxy_location || ProxyLocation.Residential, + proxyLocation: version.proxy_location ?? ProxyLocation.Residential, webhookCallbackUrl: version.webhook_callback_url || "", persistBrowserSession: version.persist_browser_session, model: version.model, diff --git a/skyvern-frontend/src/util/geoData.ts b/skyvern-frontend/src/util/geoData.ts index 63ac0ff9..6f747cb3 100644 --- a/skyvern-frontend/src/util/geoData.ts +++ b/skyvern-frontend/src/util/geoData.ts @@ -149,6 +149,15 @@ export function geoTargetToProxyLocationInput( return ProxyLocation.ResidentialISP; } + // Guard against malformed subdivision (e.g., boolean instead of string) + if (target.subdivision != null && typeof target.subdivision !== "string") { + console.error( + "[geoTargetToProxyLocationInput] Invalid subdivision:", + target.subdivision, + ); + target = { ...target, subdivision: undefined }; + } + // Try to map back to legacy enum if it's just a country if (target.country && !target.subdivision && !target.city) { const legacyLocation = COUNTRY_TO_PROXY_LOCATION[target.country]; diff --git a/skyvern/forge/sdk/db/utils.py b/skyvern/forge/sdk/db/utils.py index 6f768160..e2cb29a0 100644 --- a/skyvern/forge/sdk/db/utils.py +++ b/skyvern/forge/sdk/db/utils.py @@ -109,6 +109,11 @@ def _deserialize_proxy_location(value: str | None) -> ProxyLocationInput: if value.startswith("{"): try: data = json.loads(value) + # Handle malformed subdivision (e.g., boolean instead of string) + subdivision = data.get("subdivision") + if subdivision is not None and not isinstance(subdivision, str): + LOG.warning("Malformed subdivision in proxy_location", db_value=value, subdivision=subdivision) + data["subdivision"] = None result = GeoTarget.model_validate(data) LOG.info( "Deserialized proxy_location as GeoTarget", @@ -116,8 +121,8 @@ def _deserialize_proxy_location(value: str | None) -> ProxyLocationInput: result=str(result), ) return result - except (json.JSONDecodeError, ValueError): - pass + except (json.JSONDecodeError, ValueError) as e: + LOG.warning("Failed to parse proxy_location as GeoTarget", db_value=value, error=str(e)) # Try as ProxyLocation enum try: