From e4102bf0fb1b1ab191a218a77cc48addc5b7881e Mon Sep 17 00:00:00 2001 From: Zamil Majdy Date: Tue, 2 Dec 2025 18:02:21 +0700 Subject: [PATCH] fix(backend): resolve HITL execution context validation and re-enable tests (#11509) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary Fix critical validation errors in GraphExecutionEntry and NodeExecutionEntry models that were preventing HITL block execution, and re-enable HITL test suite. ## Root Cause After introducing ExecutionContext as a mandatory field, existing messages in the execution queue lacked this field, causing validation failures: ``` [GraphExecutor] [ExecutionManager] Could not parse run message: 1 validation error for GraphExecutionEntry execution_context Field required [type=missing, input_value={'user_id': '26db15cb-a29... ``` ## Changes Made ### ๐Ÿ”ง Execution Model Fixes (`backend/data/execution.py`) - **Add backward compatibility**: `execution_context: ExecutionContext = Field(default_factory=ExecutionContext)` - **Prevent shared mutable defaults**: Use `default_factory` instead of direct instantiation to avoid mutation issues - **Ignore unknown fields**: Add `model_config = {"extra": "ignore"}` for future compatibility - **Applied to both models**: GraphExecutionEntry and NodeExecutionEntry ### ๐Ÿงช Re-enable HITL Test Suite - **Remove test skips**: Remove `pytestmark = pytest.mark.skip()` from `human_review_test.py` - **Remove test skips**: Remove `pytestmark = pytest.mark.skip()` from `review_routes_test.py` - **Restore test coverage**: HITL functionality now properly tested in CI ## Default ExecutionContext Behavior When execution_context is missing from old messages, provides safe defaults: - `safe_mode: bool = True` (HITL blocks require approval by default) - `user_timezone: str = "UTC"` (safe timezone default) - `root_execution_id: Optional[str] = None` - `parent_execution_id: Optional[str] = None` ## Impact - โœ… **Fixes deployment validation errors** in dev environment - โœ… **Maintains backward compatibility** with existing queue messages - โœ… **Restores proper HITL test coverage** in CI - โœ… **Ensures isolation**: Each execution gets its own ExecutionContext instance - โœ… **Future-proofs**: Protects against message format changes ## Testing - [x] HITL test suite re-enabled and should pass in CI - [x] Existing executions continue to work with sensible defaults - [x] New executions receive proper ExecutionContext from caller - [x] Verified `default_factory` prevents shared mutable instances ## Files Changed - `backend/data/execution.py` - Add backward-compatible ExecutionContext defaults - `backend/data/human_review_test.py` - Re-enable test suite - `backend/server/v2/executions/review/review_routes_test.py` - Re-enable test suite Resolves the "Field required" validation error preventing HITL block execution in dev environment. ๐Ÿค– Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude Co-authored-by: Claude --- autogpt_platform/backend/backend/data/execution.py | 8 ++++++-- .../backend/backend/data/human_review_test.py | 4 ---- .../server/v2/executions/review/review_routes_test.py | 4 ---- 3 files changed, 6 insertions(+), 10 deletions(-) diff --git a/autogpt_platform/backend/backend/data/execution.py b/autogpt_platform/backend/backend/data/execution.py index c7c54ef268..3a9a629dc6 100644 --- a/autogpt_platform/backend/backend/data/execution.py +++ b/autogpt_platform/backend/backend/data/execution.py @@ -1110,15 +1110,19 @@ async def get_latest_node_execution( class GraphExecutionEntry(BaseModel): + model_config = {"extra": "ignore"} + user_id: str graph_exec_id: str graph_id: str graph_version: int nodes_input_masks: Optional[NodesInputMasks] = None - execution_context: ExecutionContext + execution_context: ExecutionContext = Field(default_factory=ExecutionContext) class NodeExecutionEntry(BaseModel): + model_config = {"extra": "ignore"} + user_id: str graph_exec_id: str graph_id: str @@ -1127,7 +1131,7 @@ class NodeExecutionEntry(BaseModel): node_id: str block_id: str inputs: BlockInput - execution_context: ExecutionContext + execution_context: ExecutionContext = Field(default_factory=ExecutionContext) class ExecutionQueue(Generic[T]): diff --git a/autogpt_platform/backend/backend/data/human_review_test.py b/autogpt_platform/backend/backend/data/human_review_test.py index 44b34ae9f3..c349fdde46 100644 --- a/autogpt_platform/backend/backend/data/human_review_test.py +++ b/autogpt_platform/backend/backend/data/human_review_test.py @@ -13,10 +13,6 @@ from backend.data.human_review import ( process_all_reviews_for_execution, ) -pytestmark = pytest.mark.skip( - reason="Tests failing in CI due to mocking issues - skipping until refactored" -) - @pytest.fixture def sample_db_review(): diff --git a/autogpt_platform/backend/backend/server/v2/executions/review/review_routes_test.py b/autogpt_platform/backend/backend/server/v2/executions/review/review_routes_test.py index 0e282f3629..2e62641ad3 100644 --- a/autogpt_platform/backend/backend/server/v2/executions/review/review_routes_test.py +++ b/autogpt_platform/backend/backend/server/v2/executions/review/review_routes_test.py @@ -20,10 +20,6 @@ app.add_exception_handler(ValueError, handle_internal_http_error(400)) client = fastapi.testclient.TestClient(app) -pytestmark = pytest.mark.skip( - reason="Tests failing in CI due to mocking issues - skipping until refactored" -) - @pytest.fixture(autouse=True) def setup_app_auth(mock_jwt_user):