rancher/dashboard PR 19768 (codyrancher) at head 6709cc33e, tested 2026-11-04. It answers izaac's reopen of issue 15656: the pool header disables − and +, but a machine's row menu still offered Scale Down, and the autoscaler brought the node back.
Preview: rancherpr19768r.mf-created-dashboard.ui.rancher.space, built from 6709cc33e, backend mf Rancher (v2.16.0-7758e3e-head). Baseline: the shared dashboard-master preview. These files have not changed on master since it was built.
autoscale machine removes the worker that hosts these previews.created-dashboard-2-autoscale-…. There is no Scale Down, and − + are disabled. On "master: Machine Pools" it's there.t is not iterable. Reload and the rows come back.autoscale machine still offers Scale Down. Clicking it opens nothing, and the console shows reading 'nodes'.Manual, paused and bulk can't be walked by hand on this cluster, since it has one autoscaling pool and two machines. I ran those with fixtures, listed in the table below.
paused-x-a row.The YAML gives one autoscaling pool (workers) and one etcd/CP machine (cp). created-dashboard-2 has the same shape, so I walked the steps on it.
workers: Scale Down is back." The pause button is disabled: "This is the only pool left autoscaling. Pausing it would uninstall the autoscaler."cp is the last etcd machine and workers is autoscaling, so neither can run it.QA is doing this one by hand (the issue has QA/dev-automation, and IsaSih's comment asks for manual tests), so it's worth a line. A second autoscaling pool and a manual worker pool in the YAML make both steps runnable.
The note is right that a gap exists, but the cause I could reach is different, and the result is milder. Open a different cluster's detail page, then Advanced > Machines. The store then has the autoscaling machine's pool and template, but not its provisioning cluster. So inClusterSpec finds no pool spec, isAutoscalerEnabled is false, and Scale Down is listed.
Clicking it throws Cannot read properties of undefined (reading 'nodes') in the dialog's data(). No dialog opens and no write is sent. Master behaves the same. I would leave the code as is and, at most, adjust the wording of the note.
canScaleDown → notOnlyOfRoleGo to Clusters or MachineDeployments, then Advanced > Machines. The table is empty, with "All (0)" beside a nav count of 5, and the console shows TypeError: t is not iterable. Clusters is where Cluster Management opens, so this is the normal way in. A direct load works, so a reload hides it.
Why: those pages load the MachineDeployments, so pool resolves, but the provisioning clusters aren't in the store. canScaleDown then calls notOnlyOfRole(this, undefined). For any etcd or control plane machine, for (const m of all) throws. Commit 801f8de51 (issue 9973, 2023) added the ?. for this same case, which moved the crash into the helper.
Evidence: reproduced on both builds from both routes. Wrapping the getter in a try/catch in the running page brings back all 5 rows with no errors, so this throw alone causes it. I found no open issue for it, from three searches.
Possible fix, one line: pass this.cluster?.machines || []. An etcd/CP machine then answers "can't scale down" until its cluster is loaded. A unit test on it passes with the guard and fails without it. I tested this locally and did not build a preview with it.
Your call: this is outside the PR's scope, so I left it out of the suggested review. I can file an issue, or you can mention it to Cody since he's in this getter already.
cluster-autoscaling is off or the whole cluster is pausedisAutoscalerEnabledBoth match the pool header, and the PR says so for the flag. For the cluster pause, keeping scaling disabled is the decision from PR 19220 (quantity goes stale). With the flag off, the edit form still shows the quantity field (MachinePool.vue:358; read, not run), so the pool isn't stuck. I faked the flag in the browser and didn't check what the backend does in that state. No action needed.
| Case | master | PR |
|---|---|---|
| Real cluster, no fixtures (created-dashboard-2: pool1 is the only etcd/CP machine, autoscale has min 1, max 1) | ||
| Row menu, autoscaling machine | offered | hidden |
| Row menu, last etcd/CP machine | hidden | hidden |
| Pool header − and + on the autoscaling pool | disabled | disabled |
| Machine detail page, opened from the cluster page | offered | hidden |
| Machine detail page after a hard reload (pool not loaded) | hidden | hidden |
| Bulk menu with both machines selected | Scale Down listed | not listed |
| Fixtures added to the real responses in the browser (writes captured, never sent) | ||
| Row menu, manual pool | offered | offered |
| Row menu, paused pool | offered | offered |
| Row menu, etcd machine with another etcd machine left | offered | offered |
| Whole cluster paused, machine in a pool with bounds | offered, − + disabled | hidden, − + disabled |
cluster-autoscaling off, pool still has bounds | offered, − + disabled | hidden, − + disabled |
| User without update on the machine | hidden | hidden |
| Pause, then Resume, on the same page without a reload | offered throughout | hidden → offered → hidden. Saved spec stashes and restores min 1, max 4, quantity 2 |
| Bulk, only an autoscaling machine selected | Scale Down enabled | Scale Down disabled |
| Bulk, 4 selected: 2 autoscaling, 1 manual, 1 paused | Annotates all 4. autoscale 1 → 0 (below its min of 1), auto2 2 → 1 | Annotates the manual and paused machines only. Both autoscaling pools keep their quantity |
| Bulk, 2 selected, only 1 can run | "Delete 2 Machines", autoscale 1 → 0 | Dialog names the manual machine, 1 write |
| Confirm Scale Down on a manual, paused and etcd machine | annotation, plus quantity −1 on that pool only | identical writes |
| Advanced > Machines, by the route you take to get there | ||
| Direct load | hidden on every row (no pool in the store) | same |
| After this cluster's detail page | offered | hidden |
| After a different cluster's detail page | offered, dialog crashes on click, no write | same (card 2) |
| After Clusters or MachineDeployments | table blank | same (card 3) |
| Unit tests | The 8 new tests pass, and 56 of 56 across the machine, machine deployment and scale-down dialog suites. Removing the new condition fails exactly the autoscaling test. |
| Team checklist | Edit to an existing JS model, new test in TS, toStrictEqual, no i18n, style or a11y change. Master is still 2.16 (no release-2.16 branch), and milestone v2.16.0 matches the issue. |
| Other Scale Down surfaces | This action is the only reader of the machine's canScaleDown. RKE1 nodes have their own getter, and pool-level − stays guarded in the header. |
| New read on the row menu path | inClusterSpec reads annotations[…] unguarded when a template exists, and row menus now reach it. All 4 Amazon EC2 templates on mf carry the annotation, and the header already reads the same getter. Not raised. |
Record<string, any> in the test mock | Against the checklist's letter, but 5 other model tests do the same. Not raised. |
| Not tested | Real Standard User and User Base logins: I used a fixture with no update link, and the unit tests cover machine and pool permissions. The change can only hide the action, so it can't widen access. A real machine being removed: writes were captured and never sent, because the worker hosts the previews. RKE1, custom, Elemental and Harvester clusters: by reading the code only. Light and dark: no visual change. |
| Left running | Preview dashboard-pr19768. Remove with bash preview/cleanup-branch.sh dashboard pr19768. Nothing changed on mf or on the cluster beyond that preview and this page. |
Approving. I tested it against a real autoscaling pool and with manual, paused and cluster-paused pools. Scale Down goes away from the row menu, machine detail and bulk, and a mixed bulk selection now only touches machines whose pool isn't autoscaling. On master that same selection took an autoscaling pool below its minimum.
Two small things on the description, neither blocks this:
workers is disabled (it's the last autoscaling pool) and the bulk step has nothing it can act on. A second autoscaling pool and a manual worker pool would make those steps runnable.