diff --git a/autogpt_platform/backend/backend/util/workspace.py b/autogpt_platform/backend/backend/util/workspace.py index e39d51905f..930741a233 100644 --- a/autogpt_platform/backend/backend/util/workspace.py +++ b/autogpt_platform/backend/backend/util/workspace.py @@ -192,7 +192,15 @@ class WorkspaceManager: Created WorkspaceFile instance Raises: - ValueError: If file exceeds size limit or path already exists + ValueError: If file exceeds size limit, exceeds the user's + tier-based storage quota, or path already exists. + VirusDetectedError: If the virus scanner flagged the content as + malicious. Callers that want a generic failure should still + catch ``Exception``, but a specific handler lets you log this + as a security event rather than a generic write failure. + VirusScanError: If the virus scanner is unreachable or otherwise + fails. Distinct from ``VirusDetectedError`` — typically maps + to a 5xx response (infrastructure issue, retry-able). """ # Enforce file size limit max_file_size = Config().max_file_size_mb * 1024 * 1024 @@ -232,12 +240,6 @@ class WorkspaceManager: f"{format_bytes(storage_limit)} quota. " f"Delete some files or upgrade your plan for more storage." ) - if storage_limit > 0 and projected_usage / storage_limit >= 0.8: - logger.warning( - f"User {self.user_id} workspace storage at " - f"{projected_usage / storage_limit * 100:.1f}% " - f"({projected_usage} / {storage_limit} bytes)" - ) # Check if file exists at path (only error for non-overwrite case). # Done before virus scanning so a cheap duplicate-path check isn't diff --git a/autogpt_platform/backend/backend/util/workspace_test.py b/autogpt_platform/backend/backend/util/workspace_test.py index 1b45ed4c5c..676b77d992 100644 --- a/autogpt_platform/backend/backend/util/workspace_test.py +++ b/autogpt_platform/backend/backend/util/workspace_test.py @@ -239,41 +239,6 @@ async def test_write_file_rejects_upload_when_usage_already_exceeds_downgraded_l mock_storage.store.assert_not_called() -@pytest.mark.asyncio -async def test_write_file_80pct_warning_logged(manager, mock_storage, mock_db, caplog): - """write_file logs a warning when workspace usage crosses 80%.""" - created_file = _make_workspace_file() - mock_db.get_workspace_file_by_path.return_value = None - mock_db.create_workspace_file.return_value = created_file - - limit_bytes = 100 # 100 bytes total limit - current_usage = 75 # 75 bytes used → 75% before write - content = b"123456" # 6 bytes → 81% after write - - with ( - patch( - "backend.util.workspace.get_workspace_storage", - return_value=mock_storage, - ), - patch("backend.util.workspace.workspace_db", return_value=mock_db), - patch("backend.util.workspace.scan_content_safe", new_callable=AsyncMock), - patch( - "backend.util.workspace.get_workspace_storage_limit_bytes", - return_value=limit_bytes, - ), - patch( - "backend.util.workspace.get_workspace_total_size", - return_value=current_usage, - ), - ): - import logging - - with caplog.at_level(logging.WARNING, logger="backend.util.workspace"): - await manager.write_file(filename="test.txt", content=content) - - assert any("workspace storage at" in record.message for record in caplog.records) - - @pytest.mark.asyncio async def test_write_file_overwrite_not_double_counted(manager, mock_storage, mock_db): """Overwriting a file subtracts the old file size from usage check."""