Repository navigation
fix(console): a settings value that misses its declared format blocks Save (objectui#13287) - #13298
Merged
objectstack-fleet[bot] merged 1 commit intoOct 21, 2026
Conversation
… Save (objectui#13287) A url, email, phone or color value that misses the grammar its specifier type declares (ADR-0007) now blocks Save on the same path as the required check: no request, the row marked through the field-error slot with a message naming what the format expects, focus on the first. Grammars are the settings service's own (objectstack#24882), judged trimmed; empty, hidden and env-locked rows are not judged. Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XVp19E1MYUTFM3dnkwz8gB
Contributor
✅ Console Performance Budget
The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it. 📦 Bundle Size Report
Size Limits
|
objectstack-fleet
Bot
deleted the
claude/issue-13287-settings-format-check
branch
October 21, 2026 04:21
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #13287
Clause-②: no
What changed
On Save, the Settings page now judges every visible, unlocked
url,email,phoneandcolorrow whose effective value (draft over stored) is non-empty. A miss blocks the save on the same path as therequiredcheck from objectui#13239: no request goes out, each row is marked inline through thefieldErrorsslot (aria-invalidplusaria-describedbyto the message), focus moves to the first blocked row in manifest order, and the existing blocked-save toast names the rows. An empty value is left torequired.apps/console/src/pages/settings/SettingsView.tsx:emptyRequiredKeysbecomespreSaveBlocks. It runs one pass with the same visibility, lock and non-input skips, and returnsrequiredorformatper key.DECLARED_VALUE_FORMATSwithmissesDeclaredFormatdoes the judging, on the trimmed value.emailreusesvalidation.emailandurlreusesvalidation.url. Two new keys,console.settingsView.invalidPhoneandconsole.settingsView.invalidColor, name what a phone number and a hex colour take. Both are added to all ten locale packs.SETTINGS_VALIDATIONrefusal renders as before. That branch is untouched.Grammars: the settings service's own, copied from objectstack main
They come from
DECLARED_VALUE_FORMATSinservice-settings(objectstack PR #25022, merged), so the page never blocks a value the server accepts and never passes one it refuses:email:local@domainwith a dotted domain.url:scheme://..., root-relative/path,data:orblob:. This is wider than the dispatch's gloss "scheme http/https". The server accepts anyscheme://. Thebranding.logo_urlreader takes absolute or relative values, and platform storage hands back root-relative file URLs. An http(s)-only console would block values the server and the reader both serve.phone: digits, spaces and+ ( ) - ., at least 5 characters. The server has this grammar, sophoneis checked rather than left out.color:#rgb,#rgba,#rrggbbor#rrggbbaa.Acceptance notes
requiredcheck works the same way. The server, by contrast, judges only the keys a save touches. It is pinned by the test "a stored malformed value on a visible row blocks a save that edits another row".colorrow,aria-invalidandaria-describedbyland on the wrapperdiv, not on the two inputs. This is howSettingsField'swrapperalready handles a server refusal on that row type:cloneElementapplies to the outer child. The message itself still renders in the row, and focus goes to the picker. This was found by reading the code and has not been measured in a browser. It is not changed here.Tests (at
a1dd56fed7)apps/console/src/pages/settings/__tests__/SettingsView.formatCheck-13287.test.tsx, 15 tests.not a urlblocks: no request, row marked, focus on it.https://...,/logo.pngand a padded/logo.pngall save.no-reply@localhostblocks; a valid email saves.redand#12block;#1a2b3csaves.visibleand an env-locked malformed url do not block.pnpm exec vitest run --maxWorkers=1 apps/console/src/pages/settings/:Test Files 28 passed (28),Tests 233 passed (233). This covers the family that readsSettingsView.tsx, including the required-check suite.packages/i18n/src/__tests__files that read the locale packs:Test Files 56 passed (56),Tests 1003 passed (1003). The fullapps/consoleandpackages/i18ndirectories are left to CI.ablation-replace.mjs, run at the commit above. The mutation} else if (missesDeclaredFormat(became} else if (false && missesDeclaredFormat(; anchor count went 1 to 0 and the blob went4f3bc9f9bb64toc0bd531ba548. Result: 8 failed, 7 passed. Every (a), (b) and (c) block test went red; the save cases and the (d) and (e) controls stayed green. Restore: blob4f3bc9f9bb64equals the HEAD blob andgit diff HEADis empty.type-checkfor@object-ui/i18nand@object-ui/console, after the@object-ui/console^...closure build: bothDone, exit 0. Consoletsc --listFilesincludes the new test.eslintover the 12 changed files (JSON count 12): 0 errors and 3 warnings, allno-explicit-anyon pre-existingcatch (err: any)lines. With--no-inline-configthere is one more, the pre-existing suppressedreact-hooks/static-components. The base file gives the same four findings. Type-aware linting is not configured ineslint.config.js, so this diff cannot change the verdict on any untouched file.check:phantom-deps,check:self-import,check:unreferenced-sources,check:doc-example-readers,check:handler-key-reads,check:side-effects-array,check:element-data-source-declaration,check:spec-symbols,check:action-forward-parity,check:designer-field-key-parity,check:icon-record-names,check:i18n-keys,check:i18n-drift,check:i18n-designer-parity,check:i18n-dead-keys,check:control-bytes,scripts/check-hand-rolled-comment-mask.mjsandscripts/check-changeset-fixed.mjs.Changeset:
.changeset/13287-settings-format-check.md(@object-ui/consolepatch,@object-ui/i18npatch).Generated by Claude Code