docs(ui): a dashboard global filter's field resolves against the dataset object, not its dimensions (#16167) - #16266
Merged
Conversation
`## Global Filters` on the dashboards page explained `name`, date defaults and
`filterBindings`, but never said where a filter's `field` is looked up. The two
halves of the answer were written on the validation reference page in adjacent
paragraphs (`content/docs/deployment/validating-metadata.mdx:44-58`) and their
asymmetry was never named: dimensions resolve against the dataset, filter fields
against the dataset's object, so the same field can be filterable and not
group-by-able on one dataset.
Adds one section to the page authors actually read when writing `globalFilters`,
stating both resolution targets side by side, the two error-severity lint rules
that enforce them, the `filterBindings: { name: false }` opt-out, and a caveat
scoping the statement to the authorable surface.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Vbw3RPgdtqesx4azk9SbW8
This was referenced Sep 6, 2026
baozhoutao
marked this pull request as ready for review
September 6, 2026 09:18
baozhoutao
enabled auto-merge
September 6, 2026 09:18
baozhoutao
deleted the
claude/issue-16167-global-filter-resolution-docs
branch
September 6, 2026 09:56
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 #16167
Adds one section —
### Where a Filter's field Resolves— tocontent/docs/ui/dashboards.mdx, inside## Global Filters, between thenameparagraph and### Date Filter Defaults. Docs only; no source, no schema, no behaviour change.What the gap actually was
Triage (comment 5556889150) corrected the card's premise, and re-reading
origin/mainconfirms the correction: two of the four facts are already written down, oncontent/docs/deployment/validating-metadata.mdx.validating-metadata.mdx:44-47— "A dashboard widget points at adatasetand readsdimensions/valuesfrom it." (dimensions resolve against the dataset)validating-metadata.mdx:49-58— "os validatefails when a filter's effective field — after any per-widgetfilterBindingsre-target — is absent on the widget's dataset object … Opt a widget out withfilterBindingsset to false for that filter."So the gap is not "unwritten". It is that the two resolution targets sit in adjacent paragraphs on a validation reference page and their asymmetry is never named — nobody states that filter
fieldand widgetdimensionsare two different namespaces, which is why the same field can be filterable and not group-by-able on one dataset. The new section states that side by side on the page authors read when writingglobalFilters, and links out to the validation page rather than duplicating it.Readings taken on
origin/main(0e16fc4), platform sidepackages/lint/src/validate-widget-bindings.ts:const datasetObject = typeof dataset.object === 'string' ? dataset.object : undefined;:857const verdict = resolveFieldPath(graph, datasetObject, field);— the filter field resolves againstdataset.object, neverdataset.dimensions:877DASHBOARD_FILTER_FIELD_UNKNOWN,severity: 'error'(dotted-path arm):900/:901DASHBOARD_FILTER_FIELD_UNKNOWN,severity: 'error'(bare-name arm):917/:918dimensionNamesbuilt fromrecordsOf(dataset.dimensions)byname; a widget dimension is accepted iffdimensionNames.has(...):1057-1060,:1068-1070WIDGET_DIMENSION_UNKNOWN,severity: 'error'— hint reads "Widgets select dataset dimensions BY NAME.":1072/:1073Also read and reflected in the wording: a dotted
relationship.fieldfilter path resolves hop by hop and additionally requires its prefix to be declared in the dataset'sinclude(WIDGET_FILTER_FIELD_NOT_INCLUDED,:1040-1053) — so the section says "the object's own fields, or a dotted path whose prefix is ininclude" rather than the flatter "the object's own fields".The card's query-layer readings (
ObjectQLStrategy.resolveFieldName,planCrossObject,combineFilters) were not re-derived here and are not cited in the doc. The query layer appears only as the layering caveat below.Why the layering caveat is there
The card asked for it and triage required it: the "cannot group by" rule holds at the authoring layer, enforced by
widget-dimension-unknown; at the raw analytics-query layer an object's own field may be used as a dimension without the dataset declaring it. The section therefore closes by scoping itself to the authorable surface explicitly, so it cannot be read as a claim about the query API.Scope
content/docs/ui/dashboards.mdx, +36 lines, no deletions.os:checktranscript surface is unchanged.content/docs/references/ui/dashboard.mdxis auto-generated from the spec.describe()strings and was not touched;globalFilters[].fielddescribe text should say the name resolves against the dataset OBJECT, not its dimensions (generated reference page, spec describe string) #16256 remains open for that lane.skip-changesetapplied.Gates — all pinned to head
940152c1cDerived with
node scripts/pm/dispatch-gates.mjs --commands content/docs/ui/dashboards.mdx→ 38 commands. All 38 run, all exit 0. Highlights:check:doc-anchors0 (validates the three new links, including the cross-pagevalidating-metadata#2-dangling-widget-bindingsanchor),check:docs-single-h10,check:docs-section-name0,check:doc-authoring0,check:docs-transcript-drift0,check:nul-bytes0,pnpm --filter @objectstack/spec run check:docs0,check:skill-examples0.Three gates first returned exit 3
PREREQUISITE NOT MET(@objectstack/lintunbuilt) andcheck:skill-examplesexit 1 for an unbuilt@objectstack/client-react— none of those was a finding; afterpnpm --filter '@objectstack/lint...' --filter '@objectstack/formula...' --filter '@objectstack/spec...' buildand--filter '@objectstack/client-react...' build(both throughscripts/pm/os-verify-lock.sh,VERDICT command-exit 0), all four re-ran to 0.Repo-wide scans (
pnpm lintand the rest of the lint workflow) are left to CI.Generated by Claude Code