From 2e7685aaa20a7b908c202dc2e724465eb2ba90a2 Mon Sep 17 00:00:00 2001 From: Robert Date: Sun, 19 Jul 2026 13:35:04 -0300 Subject: [PATCH] degrade optional workspace writes safely --- agent.py | 6 +++++- tests/test_full_stack_contract.py | 19 +++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/agent.py b/agent.py index bd678cb..2da9ed2 100644 --- a/agent.py +++ b/agent.py @@ -409,7 +409,11 @@ def _read_uploaded_workspace_file(ctx: RunContext[PlatformUserAuth], path: str) async def _write_workspace_output(ctx: RunContext[PlatformUserAuth], path: str, payload: dict[str, Any], warnings: list[str]) -> None: data = json.dumps(payload, indent=2, sort_keys=True).encode("utf-8") - workspace = ctx.workspace + try: + workspace = ctx.workspace + except PermissionError as exc: + warnings.append(f"workspace write skipped: {str(exc)[:160]}") + return writer = getattr(workspace, "write_bytes", None) if callable(writer): writer(path, data) diff --git a/tests/test_full_stack_contract.py b/tests/test_full_stack_contract.py index 79ec763..cc28363 100644 --- a/tests/test_full_stack_contract.py +++ b/tests/test_full_stack_contract.py @@ -115,6 +115,25 @@ def test_invalid_schema_returns_structured_validation_error(): assert "type='object'" in " ".join(result.warnings) +def test_optional_workspace_write_is_skipped_without_a_workspace(): + class NoWorkspaceContext: + @property + def workspace(self): + raise PermissionError("no workspace bound") + + warnings = [] + asyncio.run( + agent_module._write_workspace_output( + NoWorkspaceContext(), + "outputs/data-workflows/test.workflow.json", + {"ok": True}, + warnings, + ) + ) + + assert warnings == ["workspace write skipped: no workspace bound"] + + def test_workflow_spec_has_no_secret_fields(): schema = {"type": "object", "properties": {"Name": {"type": "string"}}, "required": ["Name"]} profile = agent_module._profile_source_data("x.csv", "text/csv", b"Name\nAda\n")