moonming opened a new issue, #3414:
URL: https://github.com/apache/apisix-dashboard/issues/3414
### Issue description
Opening a route (or service / stream route) whose **inline upstream has
health checks configured**, clicking **Edit**, and clicking **Save without
changing anything** silently deletes `upstream.checks` from the resource. The
UI shows a green "Edit Route Successfully" toast; the health checks are gone.
Reproduced on `master` (`9979b31`) against a real APISIX instance.
### Root cause
The detail pages' refetch-reset path uses the wrong producer for the
health-check UI flags:
- The health-check section is driven by a form-root-level virtual flag:
`FormSectionChecks.tsx` registers `__checksEnabled` **unprefixed** and reads it
via `useWatch({ name: '__checksEnabled' })`.
- `src/routes/routes/detail.$id.tsx` resets the form with
`produceToNestedUpstreamForm(routeData.value)`, but that producer
(`src/components/form-slice/FormPartUpstream/util.ts:34-49`) writes the flags
**nested** under `upstream.__checksEnabled` (it only sets root-level flags `if
(d.checks)`, which routes/services never have at the top level).
- After the reset, the root-level watch reads `undefined` → the checks
section renders as "disabled" → its inputs unmount → with `shouldUnregister:
true` on the form, `upstream.checks` is omitted from the PUT body → the Admin
API PUT replaces the resource without checks.
Affected pages (same reset pattern): `routes/detail.$id.tsx`,
`services/detail.$id/index.tsx`, `stream_routes/detail.$id.tsx`.
### How to Reproduce
1. Create a route with an inline upstream carrying active health checks via
the Admin API:
```bash
curl -X PUT http://127.0.0.1:9180/apisix/admin/routes/checks-repro \
-H "X-API-KEY: $KEY" -d '{
"uri": "/checks-repro",
"upstream": {
"type": "roundrobin",
"nodes": {"127.0.0.1:8000": 1},
"checks": {"active": {"type": "http", "http_path": "/health",
"healthy": {"interval": 2, "successes": 2},
"unhealthy": {"interval": 2, "http_failures": 3}}}
}}'
```
2. Open the route's detail page in the dashboard → **Edit** → **Save**
(change nothing).
3. `GET /apisix/admin/routes/checks-repro` → `upstream.checks` is gone.
### Expected behavior
A save that changes nothing must be a no-op: the resource read back after
save is identical to what was there before (health checks included).
### Why this is severe
This is silent data loss on the most routine action in the product — a user
editing a route's description destroys their health-check configuration with
zero feedback. It is also invisible to the current e2e suite: no round-trip
test asserts field preservation across a no-op edit-save.
### Suggested fix
Make `produceToNestedUpstreamForm` also derive the root-level flags from the
nested upstream:
```ts
if (d.upstream && typeof d.upstream === 'object' &&
!Array.isArray(d.upstream)) {
d.upstream = produceToUpstreamForm(d.upstream, d.upstream);
d.__checksEnabled = !!(d.upstream as Upstream).checks &&
isNotEmpty((d.upstream as Upstream).checks);
d.__checksPassiveEnabled = !!(d.upstream as Upstream).checks?.passive &&
isNotEmpty(...);
}
```
plus a regression e2e: `route detail preserves upstream.checks after no-op
edit-save`. I'm preparing a PR.
### Environment
- apisix-dashboard: master (`9979b31`), UI served by `pnpm dev` against
APISIX master via the standard `/apisix/admin` proxy
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]