Found while fixing objectui#9038 (PR objectui#9149). Filed rather than fixed there: different read site, different package, and outside that card's stated acceptance, which scopes title to the dashboard surface and subtitle/description to both.
The defect
packages/plugin-report/src/DatasetReportRenderer.tsx paints the report chart's heading itself, as an h3 above the plot, from a narrowing of its own inside DatasetReportChart:
const title = typeof chart.title === 'string' ? chart.title : undefined;
...
{title ? <h3 className="mb-2 text-sm font-semibold">{title}</h3> : null}
@objectstack/spec types ReportChartSchema.title (same keys as ChartConfigSchema) as I18nLabel — a plain string OR an inline locale map — so this is authored surface:
{ "chart": { "type": "bar", "xAxis": "stage", "yAxis": "amount", "title": { "zh-CN": "定价", "en": "Pricing" } } }
The map arm fails typeof chart.title === 'string', title is undefined, the h3 is not rendered, and the report chart draws no heading at all, in every language, with no diagnostic. Same failure mode as objectui#9038: not the wrong language — no language, so it is invisible to any check that asks whether a heading matches the locale.
Why objectui#9038 does not cover it
That card's subject is the SHARED lowering chartConfigPresentation (@object-ui/core), which both dataset-bound surfaces call. Its fix makes title/subtitle/description travel as the spec's union so the renderer resolves them against the viewer's language. But DatasetReportChart deliberately DROPS title from that result — it paints its own heading, and forwarding it as well would draw a second one inside the chart's own frame — and then reads chart.title again, through the string-only narrowing above. So on the report surface subtitle and description are fixed by objectui#9038 and title is not.
The source now says so by name: chartConfigPresentation's doc comment ledgers this read site as still unresolved, and DatasetReportRenderer.chartLocaleChrome-9038.test.tsx states in its scope note that the gap is reported rather than pinned, because pinning it would record a live defect as an expectation.
Reachability — measured, not assumed
The language is already in scope at the read site: DatasetReportChart calls useObjectTranslation() for the authored series label a few lines above, and the file already imports pickLocalized from @object-ui/i18n and resolves measure labels through it. The heading is the one authored string on this surface that does not route through it.
Suggested shape (not a ruling)
Resolve the same way everything else on this surface already does — pickLocalized(chart.title, language) || undefined — so pickLocalized stays the one resolver for the union. Worth confirming in the same pass whether the single-value metric branch (which renders the same title variable above its number) is covered by one change, since both branches read the one binding.
Acceptance
- A report chart whose
chart.title is an inline locale map renders its h3 heading in the active language, for at least two languages, rendered rather than returned from a helper.
- A plain-string title is unchanged.
- The chart is still NOT handed a title, so no second heading is drawn inside its frame.
Refs: objectui#9038, objectui#8943, objectui#4020, objectui#4877.
Reported from the os-dev seat while landing PR objectui#9149; session reference session_01UzHd6hDYatoDn17BuwKxnZ. Generated with Claude Code.
Generated by Claude Code
Found while fixing objectui#9038 (PR objectui#9149). Filed rather than fixed there: different read site, different package, and outside that card's stated acceptance, which scopes
titleto the dashboard surface andsubtitle/descriptionto both.The defect
packages/plugin-report/src/DatasetReportRenderer.tsxpaints the report chart's heading itself, as anh3above the plot, from a narrowing of its own insideDatasetReportChart:@objectstack/spectypesReportChartSchema.title(same keys asChartConfigSchema) asI18nLabel— a plain string OR an inline locale map — so this is authored surface:{ "chart": { "type": "bar", "xAxis": "stage", "yAxis": "amount", "title": { "zh-CN": "定价", "en": "Pricing" } } }The map arm fails
typeof chart.title === 'string',titleisundefined, theh3is not rendered, and the report chart draws no heading at all, in every language, with no diagnostic. Same failure mode as objectui#9038: not the wrong language — no language, so it is invisible to any check that asks whether a heading matches the locale.Why objectui#9038 does not cover it
That card's subject is the SHARED lowering
chartConfigPresentation(@object-ui/core), which both dataset-bound surfaces call. Its fix makestitle/subtitle/descriptiontravel as the spec's union so the renderer resolves them against the viewer's language. ButDatasetReportChartdeliberately DROPStitlefrom that result — it paints its own heading, and forwarding it as well would draw a second one inside the chart's own frame — and then readschart.titleagain, through the string-only narrowing above. So on the report surfacesubtitleanddescriptionare fixed by objectui#9038 andtitleis not.The source now says so by name:
chartConfigPresentation's doc comment ledgers this read site as still unresolved, andDatasetReportRenderer.chartLocaleChrome-9038.test.tsxstates in its scope note that the gap is reported rather than pinned, because pinning it would record a live defect as an expectation.Reachability — measured, not assumed
The language is already in scope at the read site:
DatasetReportChartcallsuseObjectTranslation()for the authored series label a few lines above, and the file already importspickLocalizedfrom@object-ui/i18nand resolves measure labels through it. The heading is the one authored string on this surface that does not route through it.Suggested shape (not a ruling)
Resolve the same way everything else on this surface already does —
pickLocalized(chart.title, language) || undefined— sopickLocalizedstays the one resolver for the union. Worth confirming in the same pass whether the single-value metric branch (which renders the sametitlevariable above its number) is covered by one change, since both branches read the one binding.Acceptance
chart.titleis an inline locale map renders itsh3heading in the active language, for at least two languages, rendered rather than returned from a helper.Refs: objectui#9038, objectui#8943, objectui#4020, objectui#4877.
Reported from the os-dev seat while landing PR objectui#9149; session reference
session_01UzHd6hDYatoDn17BuwKxnZ. Generated with Claude Code.Generated by Claude Code