[BYO-S3] Require a warehouse for every execution while the feature is enabled
- Dominant language
- Scala
- Stars
- 314
- Forks
- 187
- Avg merge
- 1d 21h
- Merged PRs (30d)
- 214
Description
### Task Summary
Part of #6870, follow-up to #6932. With per-user warehouses enabled, an execution that carries no `warehouseId` silently writes to the shared default warehouse: `WorkflowService.resolveWarehouseName` maps `None` to `None` whenever the flag is on. So "with the feature enabled, a run writes into the user's own warehouse" is a UI convention, not a system property — the frontend (#6933) preselects a warehouse and blocks Run until one is selected, but nothing enforces it below that.
This is not a privilege issue: an explicit `whid` is still checked against the caller's `uid`. What is missing is the requirement itself, and one path already violates it — agent-driven runs go through `POST /execution/{wid}/{cuid}/run`, where `SyncExecutionResource` hardcodes `warehouseId = None`, so on a deployment that enabled the feature every agent execution lands in the shared warehouse.
Exactly two entry points funnel into `initExecutionService`, and the requirement lands differently on each:
- **The shared funnel rejects instead of falling back** (`WorkflowService.resolveWarehouseName`): with the flag on and no `warehouseId`, fail the execution rather than routing it into the shared warehouse. The websocket path then needs nothing more — the UI always sends its pick.
- **The sync endpoint resolves the warehouse server-side** before building its `WorkflowExecuteRequest`, instead of hardcoding `None`: the workflow's latest execution's warehouse when it still exists and belongs to the caller (`workflow_executions.whid`), else the caller's earliest-created warehouse — the same rule the UI preselect applies — failing only when the caller has no warehouse at all. An optional explicit `warehouseId` parameter can override. It is authenticated (`@Auth SessionUser`), so the lookup is straightforward.
The agent service stays untouched. `cuid` reaches it only because each computing unit is a separate pod and the execution endpoint is addressed per-`cuid` — a routing concern; the warehouse plays no role in routing, so the server resolves it instead of threading storage context through a service that has no use for it.
Flag-off behaviour is unchanged: an explicit pick is still refused loudly (#6930) and no pick still means the shared warehouse; the wire type stays `Option[Int]`. Worth settling while the flag is off everywhere — tightening this later, once a deployment runs with the lenient fallback, would break callers that work today.
### Task Type
- [x] Other (feature implementation)
Contributor guide
Assessment
This issue has not been assessed yet.