Deploying with no site registered hangs in Deploying instead of raising an error
What happens
Deploying a workflow on an engine with no site registered (no worker chart installed) leaves the deployment stuck in Deploying forever. Nothing in the UI says why, and the deployment never fails — it just never progresses.
Reproduced on a local install (docker-compose + ryax-engine 26.9.0-rc4, no
ryax-worker-k8s release, so site is empty), following the README "Test
locally with Kubernetes in Docker" flow but skipping the worker step.
Why
BaseScheduler.schedule() reads the sites and hands them to the placement
policy:
# core/ryax/runner/application/scheduler.py:69
with self.uow_factory() as uow:
pending_connections = uow.execution_repository.list_pending()
sites = uow.site_repository.list() # [] when no worker is registered
...
sched_result = await self._place(pending_connections, sites)InternalScheduler._place() only turns a placement failure into a user-visible
error for two exception types:
# core/ryax/runner/application/internal_scheduler.py:65
try:
node_pool = self.site_placement_service.schedule_one(sites, connection)
allocations.append((connection.id, node_pool.id))
except (NoResourcesFoundWithConstraints, NotEnoughResourcesException) as err:
errors.append((connection.id, f"Unable to schedule the Execution ..."))With sites == [], _resolve_candidate_node_pools() yields no candidates and
the execution produces neither an allocation nor an error, so it stays pending
and is retried on every scheduling round indefinitely. "No sites at all" is a
different condition from "no site matches the constraints", and it is not
reported as either.
The empty-site case also breaks the metrics path, which assumes a site was always chosen:
File "ryax/runner/application/handlers/execution_handlers.py", line 585,
in on_demand_complete_execution_metric
assert execution.site_id is not None
AssertionErrorThat fires from the on_error retry chain
(execution_handlers.py:247, "proceeding with retry chain anyway"), so it is a
symptom rather than the cause — but a bare assert on operational state will
keep producing noisy tracebacks whenever site_id is unset.
Expected
Deploying with no usable site should fail fast with a message the user can act on — something like "No site is registered: install a worker chart before deploying" — surfaced on the deployment in the UI, rather than hanging in Deploying.
Suggested fix
- In
schedule()or_place(), treat an empty site list (and an empty candidate node-pool list) as an explicit scheduling error, so it flows through the existingExecutionErroredEventpath already used forNoResourcesFoundWithConstraints. - Distinguish the two cases in the message: no site registered at all vs no site satisfies the constraints. The first is a setup problem, the second a capacity/constraint problem.
- Replace the
assert execution.site_id is not Noneatexecution_handlers.py:585with a guarded early return, so an execution that never got a site does not raise inside the error handler.
Notes
This is most likely to hit new users: the README's local-install flow installs the engine first and the worker afterwards, so there is a window where the platform is up, the UI is usable, and deploying silently hangs.