From 336cd3acc41c01af7fa1acf37c713227cf751858 Mon Sep 17 00:00:00 2001 From: Tsai Yuan <136825049+nothingyuancando@users.noreply.github.com> Date: Mon, 24 Aug 2026 15:27:33 +0800 Subject: [PATCH] fix(sandbox): reject non-finite ownership timings (#4960) --- backend/packages/harness/deerflow/config/sandbox_config.py | 2 ++ backend/tests/test_sandbox_ownership_store.py | 7 +++++++ 2 files changed, 9 insertions(+) diff --git a/backend/packages/harness/deerflow/config/sandbox_config.py b/backend/packages/harness/deerflow/config/sandbox_config.py index 344653d47..7b7144424 100644 --- a/backend/packages/harness/deerflow/config/sandbox_config.py +++ b/backend/packages/harness/deerflow/config/sandbox_config.py @@ -29,6 +29,7 @@ class SandboxOwnershipConfig(BaseModel): renewal_interval_seconds: float = Field( default=30.0, gt=0, + allow_inf_nan=False, description=( "How often an owning instance refreshes its leases. The lease TTL is derived from this (interval x ttl_multiplier), so ownership liveness is independent of sandbox.idle_timeout: " "renewal keeps running even when idle cleanup is disabled (idle_timeout: 0)." @@ -37,6 +38,7 @@ class SandboxOwnershipConfig(BaseModel): ttl_multiplier: float = Field( default=4.0, ge=2, + allow_inf_nan=False, description="Lease TTL as a multiple of renewal_interval_seconds. At least 2, so a single missed renewal (slow host, brief Redis blip) cannot expire a live owner's lease. Default 4 tolerates three consecutive misses.", ) key_prefix: str = Field( diff --git a/backend/tests/test_sandbox_ownership_store.py b/backend/tests/test_sandbox_ownership_store.py index 55d6aca2c..89bfe4001 100644 --- a/backend/tests/test_sandbox_ownership_store.py +++ b/backend/tests/test_sandbox_ownership_store.py @@ -356,6 +356,13 @@ def test_ttl_multiplier_below_two_is_rejected(): SandboxOwnershipConfig(ttl_multiplier=1.0) +@pytest.mark.parametrize("field", ["renewal_interval_seconds", "ttl_multiplier"]) +@pytest.mark.parametrize("value", [float("inf"), float("-inf"), float("nan")]) +def test_lease_timing_rejects_non_finite_values(field, value): + with pytest.raises(ValueError): + SandboxOwnershipConfig(**{field: value}) + + def test_owner_ids_are_unique_per_instance(): """Two workers on one host must not share an owner id.""" assert generate_owner_id() != generate_owner_id()