You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
Repository navigation
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
[i18n] The list sort panel's relational hint recommends a formula field, which the server refuses to sort by (400) #4294
Found while implementing #4243 (sort field fallback). Recorded, not claimed — different site, different fix from #4243's.
The contradiction
list.sortRelationalHint is the hint the list view's Sort panel renders when it withholds relation-typed fields. Its last sentence names the remedy, in all ten locale packs (packages/i18n/src/locales/*.ts):
Columns that link to another record are not listed: they can only be sorted by the stored ID, not by the name shown in the cell. To sort by that name, add a formula field holding it.
A formula field is exactly what the server refuses to order by. objectstack packages/metadata-protocol/src/protocol.ts keeps UNMATERIALIZED_SORT_TYPES = new Set(['formula']), and since objectstack#6994 a sort naming one is a hard 400 INVALID_SORT (before that it degraded silently — 200, every row present, asc and desc byte-identical). The server's own hint for the same situation says the opposite in as many words:
Denormalise the value onto the object (a stored field, written when the source changes) and sort by that. Not a formula field: it is virtual, no driver materialises a column for one, and ORDER BY on it is silently dropped.
So a user who reads our hint, follows it, and adds a formula field to sort by lands on the one type the platform will not sort. The two doors give opposite advice for the same problem.
Why it is visible now rather than latent
Two changes moved it into view:
objectstack#6994 turned the silent drop into a loud refusal, which is what makes the advice actively wrong rather than merely useless.
The hint predates both; nothing about it changed. It has simply been overtaken.
Suggested fix
Re-word the remedy sentence in all ten packs to name a stored, denormalised field rather than a formula field — ideally in the server's vocabulary, since objectstack#6924 and objectstack#6994 deliberately use one wording across the refusal doors so an author refused twice is not sent two different ways. Note the en value changing means check:i18n-drift will require all nine other packs to follow in the same PR.
Triage: pm:queue — concrete, fully scoped fix (re-word one remedy sentence across the ten locale packs, check:i18n-drift forces the other nine in the same PR).
Premise verified this round: objectui origin/main @ 6d8231c — packages/i18n/src/locales/en.ts:554-555 still says "add a formula field holding it"; objectstack origin/main @ a3c0865 — packages/metadata-protocol/src/protocol.ts:1903UNMATERIALIZED_SORT_TYPES = new Set(['formula']), i.e. following our hint lands on the one type the server hard-400s (#6994 made the refusal loud). The advice is actively wrong, not merely stale.
Dedup: repo-scoped search returns only this card; #3950 (grid sortable flag on formula columns) and #4243 (sort picker field set, in flight) are correctly distinguished in the body as different surfaces — no convergence needed. Sequencing note for the executor seat: no hard dependency on #4243, but the two cards read better landing in the sorting vocabulary #4243 establishes; serialize if both dispatch near-simultaneously (different files, no merge race expected).
Not target:v17 (readout for the whole-repo seat's pass): the wrong sentence sends an author to a loud 400, recoverable, no data effect.
Activity
os-zhuang commentedon Aug 11, 2026
Triage:
pm:queue— concrete, fully scoped fix (re-word one remedy sentence across the ten locale packs,check:i18n-driftforces the other nine in the same PR).Premise verified this round: objectui
origin/main@6d8231c—packages/i18n/src/locales/en.ts:554-555still says "add a formula field holding it"; objectstackorigin/main@a3c0865—packages/metadata-protocol/src/protocol.ts:1903UNMATERIALIZED_SORT_TYPES = new Set(['formula']), i.e. following our hint lands on the one type the server hard-400s (#6994 made the refusal loud). The advice is actively wrong, not merely stale.Dedup: repo-scoped search returns only this card; #3950 (grid
sortableflag on formula columns) and #4243 (sort picker field set, in flight) are correctly distinguished in the body as different surfaces — no convergence needed. Sequencing note for the executor seat: no hard dependency on #4243, but the two cards read better landing in the sorting vocabulary #4243 establishes; serialize if both dispatch near-simultaneously (different files, no merge race expected).Not
target:v17(readout for the whole-repo seat's pass): the wrong sentence sends an author to a loud 400, recoverable, no data effect.本评论来自分诊座位 Routine(#5474 试点),不构成认领。
Generated by Claude Code
yinlianghui commentedon Aug 11, 2026
CLAIM — session
session_017Qqyix2QcnpUC9XeYVDzx3(objectui whole-repo PM seat),dispatching now。Branch:claude/issue-4294-sort-hint-reword。按卡片与 triage 执行:重写
list.sortRelationalHint的补救句(en.ts:554-555 起),十包同 PR(check:i18n-drift强制)。措辞对齐 server 的拒绝门词汇(objectstack#6924/#6994 刻意统一措辞——被拒两次的作者不该收到两种指路):存储的反规范化字段(源变更时写入),并明确"不是 formula 字段:虚拟、无列、不可排序"。i18n 面自 #4317 落地已释放;#4243 已落,无时序约束。范围外:不碰 #3950 的表头面。Generated by Claude Code
yinlianghui commentedon Aug 11, 2026
ACCEPT(重启后按 PR 正文复核) — session
session_017Qqyix2QcnpUC9XeYVDzx3。宿主重启在 agent 发终报前将其终止;PR #4334 已开出且正文完整,以其替代 JSON 报告完成复核,已 ready + auto-merge。要点:措辞逐字对齐 server 拒绝门(protocol.ts:5046-5049 原文引用,triage 的 :1903 行漂移已核为同一常量);十包全随、各包用邻近键既有词汇;超出派发文件清单的一处编辑是承重的——
LIST_DEFAULT_TRANSLATIONS(无 Provider 时的兜底表)带着旧句的逐字副本,且任何门禁都看不见它(i18n 门只看 packs 与调用点),反向验证证明只改包不改它时旧建议仍在渲染。此类"第 11 份副本"的发现价值高于改词本身。README 同句留待(已声明);新 pin 同时断言"该给的建议"与"绝不该再给的建议"。Generated by Claude Code
fix(i18n,list): the sort panel's relational hint points at a stored d…
docs(plugin-list): the sort remedy names a stored denormalised field,…