Skip to content

fix(ui+http): timezone validator + system-configs 404 noise#1173

Open
vanducng wants to merge 1 commit into
nextlevelbuilder:devfrom
dataplanelabs:upstream-fix/timezone-validator-sysconfig-404
Open

fix(ui+http): timezone validator + system-configs 404 noise#1173
vanducng wants to merge 1 commit into
nextlevelbuilder:devfrom
dataplanelabs:upstream-fix/timezone-validator-sysconfig-404

Conversation

@vanducng

@vanducng vanducng commented May 25, 2026

Copy link
Copy Markdown
Contributor

Summary

Two small quick-fixes that surfaced together on a fork dashboard but apply identically to upstream/dev (both files unchanged from upstream).

1. Timezone save rejected with "Invalid timezone"

Saving a cron job with `Asia/Ho_Chi_Minh` (or any IANA name picked from the dropdown) failed validator and showed an "Invalid timezone" toast.

Root cause: `isValidIanaTimezone` (in `ui/web/src/lib/timezone-utils.ts`) built a `Set` from `Intl.supportedValuesOf("timeZone")` then canonicalized each name via `new Intl.DateTimeFormat(...).resolvedOptions().timeZone`. Across browser/OS combos this drops or remaps some names — e.g. on Chrome 110+ `Asia/Saigon` canonicalizes to `Asia/Ho_Chi_Minh` but on older Safari/Firefox it stays `Asia/Saigon`. When the user's stored value happens to be the absent form, save fails despite the value being a valid IANA name.

Fix: validate via direct `Intl.DateTimeFormat(...)` try/catch. That's the canonical IANA validation path — accepts every name the browser's tz database understands, deprecated aliases included.

2. `/v1/system-configs/{key}` 404 console spam

`background-error-banner.tsx` polls `/v1/system-configs/alert.background.provider_error` to recover alert state after page refresh. When no alert exists (the common case), backend returned 404. The frontend's `.catch()` handled it semantically — but Chrome still logs "Failed to load resource" for every 404. Devtools console fills with hundreds of these entries.

Fix: `handleGet` returns 200 with empty `value` for missing keys. Settings-store "missing" == "empty" is the natural semantics here; the frontend's existing `if (res.value)` guard already handles both shapes. No behavior change for other callers.

Files changed

  • `ui/web/src/lib/timezone-utils.ts` — replace Set-based validator with Intl try/catch
  • `internal/http/system_configs.go` — `handleGet` returns 200 with empty value on miss

Test plan

  • `go build ./...` + `go vet ./...` green
  • `pnpm build` in `ui/web/` green
  • Manual: open a cron-job detail → pick `Asia/Ho_Chi_Minh` → Save → no toast
  • Manual: open dashboard with no active provider alert → console clean (no `/v1/system-configs/*` 404)

Notes

Tested in production on a downstream fork (dataplanelabs/goclaw v3.23.11) since 2026-05-25. Both fixes resolved the reported user-visible issues; no regressions observed across the trace/cron/alert paths.

Two small quick-fixes:

1. Timezone save rejected with "Invalid timezone" toast even when the
   user picked a valid IANA name from the dropdown. Root cause:
   isValidIanaTimezone built a Set from Intl.supportedValuesOf() then
   canonicalized each name via Intl.DateTimeFormat(...).resolvedOptions().
   Across browser/OS combos this drops or remaps some names (e.g.
   Asia/Saigon ↔ Asia/Ho_Chi_Minh varies — only one ends up in the
   rebuilt Set, depending on the browser's tz database revision).
   When the user's stored value happens to be the absent form, save
   fails. Replace with direct Intl.DateTimeFormat try/catch — the
   canonical IANA validation path; accepts every name the browser
   understands, deprecated aliases included.

2. /v1/system-configs/{key} returned 404 for missing alert keys. The
   frontend (background-error-banner.tsx) already handles this silently
   via .catch — but Chrome logs the 404 to the console regardless.
   The polled alert key (alert.background.provider_error) legitimately
   doesn't exist most of the time, so the console fills with "Failed
   to load resource" entries. Return 200 with empty value instead —
   "missing" == "empty" matches settings-store semantics, and the
   frontend's existing `if (res.value)` guard already handles both.
@mrgoonie

Copy link
Copy Markdown
Contributor

Backlog review: merge-candidate. The timezone validator change uses Intl directly, which handles canonical/deprecated IANA aliases better than the Set-based check, and the system-config missing-key behavior is intentionally fail-soft. go and web checks are passing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants