A failed deployment is silent: workflow returns to NONE with deployment_error null
Symptom
A workflow whose deployment fails returns to not deployed with
deployment_error: null. The reason exists only in the Worker logs, which a
user without cluster access cannot read. Nothing in the UI or the API says what
went wrong — or that anything went wrong at all.
Reported against 26.9.0.
Root cause — confirmed in the code
studio/ryax/studio/application/workflow_service.py:368-377:
def undeploy_workflow_success(self, workflow_id: str, error: Optional[str] = None) -> None:
with self.uow:
workflow = self.uow.workflows.get_workflow(workflow_id)
if not error:
workflow.undeploy_success() # status -> NONE
else:
workflow.undeploy_with_error(error) # status -> ERROR, message kept
self.uow.commit()error is optional and defaults to None, so any failure that arrives without
a message string takes the success branch and is indistinguishable from a
deliberate undeploy.
deployment_error is cleared at the start of every deploy
(studio/ryax/studio/domain/workflow/entities/workflow.py:653), and
undeploy_success() (:776) sets deployment_status = NONE without touching
it. So the field is reliably null on this path — there is no stale value to
notice either.
The plumbing to report this is entirely in place and unused: the column
(infrastructure/database/metadata.py:159), the API field
(infrastructure/api/models/workflow.py:49) and the view
(domain/workflow/views/workflow_view.py:33) all exist.
Reproduction
Any deployment failure that does not carry an error string — the demo hit it via the addon/definition failure filed separately, where the Worker kills the pod a few seconds after start.
Observed: GET /api/studio/workflows/<id> returns
deployment_status: "NONE", deployment_error: null, and the only account of
the failure is in the Worker pod logs.
Why it matters
It converts every deployment failure into a silent no-op for anyone without
kubectl. It also makes the failures filed alongside this one far harder to
diagnose than they need to be — the demo only found them by reading Worker logs.
Acceptance criteria
- A failed deployment leaves the workflow in
ERRORwith a non-nulldeployment_error, or it is documented why a given failure cannot carry one. - Callers of
undeploy_workflow_successare audited: which of them mean "undeployed on purpose" and which mean "failed"? The shared name and the optional argument are what allow the two to be confused.
Workaround in place
The demo checks status and URL after every deployment rather than trusting the reported state.
Found while migrating the CAPE demo to Ryax 26.9.0: ryax-tech/public/cape-tools/cape-agentic-infra#2 (comment 3905714558)