Uh oh!
There was an error while loading. Please reload this page.
fix(i18n,list): the sort panel's relational hint points at a stored denormalised field, not a formula field (#4294) - #4334
Merged
Conversation
…enormalised field, not a formula field (#4294) `list.sortRelationalHint` told an author to "add a formula field holding it" — the one field type the server refuses to order by (`UNMATERIALIZED_SORT_TYPES`, a hard 400 INVALID_SORT since objectstack#6994, and withheld from this very picker since #4243). The remedy sentence now names a stored, denormalised field written when the source changes, and rules the formula field out explicitly, in the server's own refusal-door vocabulary (objectstack#6924/#6994 keep one wording across the doors). All ten packs move together, as check:i18n-drift requires. plugin-list's provider-less fallback table carries the identical sentence, since that copy — not the pack — is what renders outside an I18nProvider. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017Qqyix2QcnpUC9XeYVDzx3
The latest updates on your projects. Learn more about Vercel for GitHub. |
Contributor
✅ Console Performance Budget
📦 Bundle Size Report
Size Limits
|
yinlianghui
marked this pull request as ready for review
August 11, 2026 17:18
Uh oh!
There was an error while loading. Please reload this page.
This was referenced Aug 11, 2026
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 freeto 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#4294
The Sort panel withholds columns that link to another record and explains why. The last sentence of that explanation named the remedy — "To sort by that name, add a formula field holding it" — and a formula field is the one type the platform will not order by. The server keeps
UNMATERIALIZED_SORT_TYPES = new Set(['formula']), and since objectstack#6994 a sort naming one is a hard400 INVALID_SORT; before that it degraded silently, returning every row withascanddescbyte-identical. Since #4243 withheld formula fields from this very picker, an author who followed the hint also arrived at a field the panel does not offer. Two doors, opposite advice, one problem.The wording, and where it comes from
The remedy now names a stored, denormalised field, written when the source changes, and rules the formula field out in as many words. That is deliberately the server's own vocabulary rather than a third phrasing: objectstack#6924 and objectstack#6994 settled on one wording across the refusal doors so an author refused twice is not sent two different ways.
Server wording source, read read-only at objectstack
origin/main@5d24f4b94:packages/metadata-protocol/src/protocol.ts:5046-5049— the hint on the unmaterialized-type refusal door (objectstack#6994), verbatim:packages/metadata-protocol/src/protocol.ts:4993-4996— the same remedy sentence on the dotted-path door, which is what "one vocabulary across the doors" means in practice.packages/metadata-protocol/src/protocol.ts:1593—UNMATERIALIZED_SORT_TYPES. (The triage comment cites:1903; on today'smainthe constant sits at:1593. Same constant, same set, line drift only.)New
envalue:The first half — why relation columns are withheld — is unchanged in every pack. Only the remedy sentence moved. Spelling follows this repo rather than the server's British form:
packages/plugin-list/README.mdalready writes "denormalize" for this exact remedy.All ten packs, and one copy that is not a pack
Ten locale packs updated (
packages/i18n/src/locales/*.ts), ascheck:i18n-driftrequires of anyenedit. Each translation matches its pack's existing register for "field" / "stored" / "formula" — the terms were taken from neighbouring keys in the same pack (theformulafield-type label, thesort*cluster, the import notices' word for "server"), not machine-translated.One edit outside the packs, and it is load-bearing:
packages/plugin-list/src/ListView.tsxholdsLIST_DEFAULT_TRANSLATIONS, the tablecreateSafeTranslationserves when noI18nProvideris mounted, and it carried a byte-identical copy of the old sentence. That copy is updated to matchenexactly. This is not belt-and-braces — it is measured. Reverting only that file, with all ten packs already holding the new text, leaves the rendered panel serving the retired advice:So a pack-only reword would have left the old advice on exactly the surface this card is about, wherever the component is used outside the console. No gate can see that:
check:i18n-keysjudges inlinet(key, { defaultValue })options at call sites, never acreateSafeTranslationtable, and the drift gate compares packs to packs. Flagging it as a deliberate, reviewable step beyond the dispatched file list — it is the same key and a pure string swap, no logic touched.Tests
No existing assertion needed updating. Both suites that read this hint (
ListView.relationalSort.test.tsx:88,ListView.sortFieldFallback.test.tsx:227) match on/can only be sorted by the stored ID/i, which lives in the unchanged first half.One pin added to
ListView.relationalSort.test.tsx— it asserts the remedy the hint gives and the one it must never give again, since "formula" still appears in the sentence, named only to be ruled out.Red-first is real here, in both directions:
zh) toorigin/mainwhileenholds the new text:EXIT=1,unchanged in: zh. Restored, green: "1 en value(s) changed, 9 pack value(s) followed ... Every changed en value was followed by all nine translation packs."ListView.tsxonly: the failure quoted above. Restored, green.Gates and suites run locally, all green:
Changeset:
patchfor@object-ui/i18nand@object-ui/plugin-list.Out of scope, filed separately
packages/plugin-list/README.md:229-230gives the same retired advice in prose ("denormalize it onto this object with a formula field"). Different surface, its own explanatory paragraph to rewrite — filed rather than ridden along, per the card's scope note.Generated by Claude Code