fix: prioritize paused/stopped status over pod_status for sandbox state

When determining sandbox status, pod_status was checked first and mapped
to SandboxStatus. However, pod_status doesn't track paused state - a
paused sandbox may still report pod_status as 'ready', which incorrectly
maps to RUNNING status.

This caused the conversation list to show a green status indicator for
paused conversations after re-fetching from the API, even though the
sandbox was successfully paused.

The fix prioritizes checking runtime status for 'paused' and 'stopped'
states first, since these are not represented in pod_status. For other
states (running, starting, error), pod_status remains the primary source
as it's more reliable for those cases.

Co-authored-by: openhands <openhands@all-hands.dev>
This commit is contained in:
openhands
2026-03-16 20:14:55 +00:00
parent 934fbe93c2
commit 9da582ac8d

View File

@@ -192,20 +192,31 @@ class RemoteSandboxService(SandboxService):
the status of a runtime is inconsistent. It is divided between a "status" which
cannot be trusted (It sometimes returns "running" for cases when the pod is
still starting) and a "pod_status" which is not returned for list
operations."""
operations.
Note: We check for "paused" status first because pod_status doesn't track
paused state - a paused sandbox may still have pod_status "ready" which
would incorrectly map to RUNNING.
"""
if not runtime:
return SandboxStatus.MISSING
# Check runtime status first for paused/stopped states that pod_status doesn't track
runtime_status = (runtime.get('status') or '').lower()
if runtime_status in ('paused', 'stopped'):
mapped_status = STATUS_MAPPING.get(runtime_status)
if mapped_status is not None:
return mapped_status
# Use pod_status for running/starting/error states (more reliable for these)
status = None
pod_status = (runtime.get('pod_status') or '').lower()
if pod_status:
status = POD_STATUS_MAPPING.get(pod_status, None)
# If we failed to get the status from the pod status, fall back to status
if status is None:
runtime_status = runtime.get('status')
if runtime_status:
status = STATUS_MAPPING.get(runtime_status.lower(), None)
# Fall back to runtime status for remaining cases
if status is None and runtime_status:
status = STATUS_MAPPING.get(runtime_status, None)
if status is None:
return SandboxStatus.MISSING