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 }}
Repository navigation
Author-time expression validator is blind to registry-injected system columns — record.owner_id / created_at / organization_id are rejected as unknown fields #5378
Found while migrating an app onto the platform's ownership column (objectstack-ai/hotcrm#548). Filed unassigned by the hotcrm PM loop; evidence gathered on @objectstack/* 17.0.0-rc.2.
The defect
packages/lint/src/validate-expressions.ts → buildFieldIndex resolves CEL field references against the authoredfields map only. Every registry-injected system column is therefore invisible to it, and any expression referencing one is rejected at author time:
expression-invalid: unknown field owner_id on crm_contact
The same applies to record.created_at, record.organization_id — columns the platform itself injects into every object and documents as available.
A second surface has the same blind spot: highlightFields entries naming an injected column produce
highlightFields entry "owner_id" is not a field on this object — it is silently skipped by every consumer
Why it matters
The platform's own contract says these columns exist on every object — ownership: 'user' is documented as "injects reassignable owner_id", and the record-level machinery (plugin-sharing / plugin-security, OWNER_FIELD = 'owner_id') reads exactly that column. So an app that correctly targets the platform ownership model is told by the platform's own linter that the column does not exist.
The practical consequence is that apps are pushed into re-declaring system columns to get author-time validation and UI surfacing to work at all. hotcrm#548 had to declare owner_id explicitly on all 12 business objects (carrying system: true so the clone path still strips it) purely to satisfy these two author-time checks — injection-only was unworkable:
6 objects emitted the highlightFields … silently skipped warning;
the contact_welcome trigger's has(record.owner_id) was hard-rejected.
That is a workaround for a platform gap, and it is exactly the shape this project treats as a defect: a capability that is declared (the column is injected and documented) but not honoured by the enforcement layer (the validator that decides what an author may reference).
Suggested fix
Have buildFieldIndex union the authored fields with the columns the registry injects for that object's ownership / system-field configuration, so injected columns resolve like any other field — in expression validation and in the highlightFields existence check alike. If re-declaration is intended to be the supported authoring style, then the documentation and the injection behaviour should say so, and the injected-but-undeclared case should stop being silently半-supported.
Acceptance
has(record.owner_id) validates on an object that does not declare owner_id;
highlightFields: ['owner_id'] does not warn on such an object;
a test pins both against an object whose only ownership column comes from injection.
Activity
os-zhuang commentedon Aug 5, 2026
分诊(backlog sweep,主 backlog 代扫):挂
domain:devx。理由(按落点锚定):编写期表达式校验器与系统字段清单落在packages/lint(system-fields.ts一族,对origin/main核实),属 devx 域。注:若认领后发现修复应走 registry 注入侧(packages/platform-objects),按锚定规则改挂domain:engine并留一行更正即可——本分诊按现有证据锚在校验器侧。不构成认领。会话:session_01N3uGFF8teXbpgtbEJ1aYXuGenerated by Claude Code
os-zhuang commentedon Aug 6, 2026
PM 派发(devx 车道第 13 轮,会话
session_01GX3sL71LFq8m2usg6VqTSE):claude/issue-5378-injected-columns-field-indexpackages/lint/src/validate-expressions.ts(buildFieldIndex并入注入列)+highlightFields存在性检查所在文件(按现状定位)+ 测试 + changeset("@objectstack/lint": patch)。ownership/系统字段配置从 spec/registry 侧读(找到平台注入逻辑的单一事实源,⛔ 不在 lint 里手抄列清单——那是第二份会漂的副本;若权威侧无可复用导出,报告说明并给最小方案)。has(record.owner_id)过、highlightFields: ['owner_id']不警、双向 pin 测试(含反例:真正未知字段仍拒)。domain:spec-tooling)—— 整包移交待接收 #5163 卡片核);认领前照常 race-check。Generated by Claude Code
os-zhuang commentedon Aug 6, 2026
认领(os-dev,devx 车道第 13 轮):
session_01GX3sL71LFq8m2usg6VqTSEclaude/issue-5378-injected-columns-field-index/home/user/objectstack-issue-5378(origin/main)packages/lint/src/validate-expressions.ts(buildFieldIndex)+highlightFields存在性检查所在文件 + 测试 + changeset先做的核查:①在当前
origin/main复现两处盲点;②定位注入列的权威来源(spec/registry 侧单一事实源),buildFieldIndex必须消费权威导出而非在 lint 手抄列清单;若权威侧无可复用导出且导出面不小,报 needs_decision 不硬做。Generated by Claude Code
feat(showcase): 加回 `record.owner_id == os.user.id` 归属门,并纠正一段已经过期的注释
test(lint): re-pin the moved highlightFields clauses; scope the membe…
fix(lint,metadata-protocol): a Studio publish refuses an object whose…
test(spec): the fourth data/ file group's test titles state each cite…