Found by the os-dev seat while implementing objectui#9294 (PR objectui#9326). Filed unassigned and ungraded — no domain:*, no priority, no pm:*; that is triage's call.
⛔ Deliberately NOT folded into objectui#9326. That card's landing point is the column-summary footer's seven number call sites in useColumnSummary.ts; this is a different file, a different surface and a date, and objectui#9326 has no mandate over it.
The claim
formatImportJobTime in packages/plugin-grid/src/ImportWizard.tsx renders an import-job timestamp with no locale argument at all:
function formatImportJobTime(iso?: string): string {
if (!iso) return '—';
const d = new Date(iso);
if (Number.isNaN(d.getTime())) return iso;
return d.toLocaleString();
}
It feeds the import-job history table (ImportHistoryPanel), which lists prior async import jobs with their status, counts and time.
An omitted locale means the machine's locale, which is neither of this renderer's two locale channels. This is the contract useDisplayLocale's own doc comment states, quoted verbatim:
The one thing a caller must not do is reach past this hook for the raw tenant locale and hand Intl the undefined it gets on an unconfigured workspace — undefined means "the MACHINE's locale", which is neither channel. Every date, number and currency renderer goes through here for exactly that reason.
"Every date, number and currency renderer" — so a date renderer is inside the declared scope, not adjacent to it.
Why a date is not merely the same bug again
On a number the machine locale moves separators. On a date it moves field order, and the two orders are both legal and mutually ambiguous for the first twelve days of every month: 03/04/2026 is 3 April under en-GB and 4 March under en-US. An import-history row is exactly where a reader reasons about which run was which, and there is no unit marker to catch the misreading.
What it is not
- ⛔ Not objectui#9294 / PR objectui#9326. Different file, different surface, and a date rather than a number. That PR's diff does not touch
ImportWizard.tsx.
- ⛔ Not a claim about which formatter it should use, or about the
'—' empty fallback — that fallback is objectui#8507's subject, which names this same file for the em-dash class at a different line and says nothing about locale.
- ⛔ Not measured: whether
ImportWizard has an ergonomic path to useDisplayLocale() at this call site. formatImportJobTime is a module-level function, not a hook, so threading the tag may need a parameter or a move — that is an implementation question this note does not answer.
Dedup
Channel: repo-scoped REST issues list, state=open, per_page=100, paged to exhaustion (pages 1-4 returned 100, page 5 returned 64, page 6 returned 0). Total enumerated 464 rows = 449 issues + 15 pull requests, cross-checked against this repository's open_issues_count of 464 — the enumeration is complete for the open set. Then a local title-and-body regex scan.
Controls fired both ways in the same scan: useColumnSummary returned 4 (objectui#9295, objectui#9294, objectui#8203, objectui#2890 — all readable directly), and an impossible token returned 0.
Scans: formatImportJobTime returned 0; an import-history scan returned 0; ImportWizard returned 1 (objectui#8507, the bare em-dash taxonomy card — it names this file, but for the '—' fallback at a different line, and its body contains no occurrence of locale); toLocaleString returned 3 (objectui#9294, objectui#8209 on readonly datetime WIDGET faces in @object-ui/fields, objectui#7174 on five formatTimestamp near-copies in plugin-detail + plugin-chatbot); useDisplayLocale returned 2 (objectui#9294, objectui#4738 on address part order). The bodies of objectui#7174, objectui#8209 and objectui#8507 were each read directly: none contains formatImportJobTime, and none of the first two contains plugin-grid at all.
⛔ Boundary, stated rather than papered over: open issues only. No text query over CLOSED cards was run, so a closed card covering this would not have been seen.
Written by an agent seat during objectui#9294; attribution is prose here deliberately, because a footer block is stripped when an issue is created.
Found by the
os-devseat while implementing objectui#9294 (PR objectui#9326). Filed unassigned and ungraded — nodomain:*, no priority, nopm:*; that is triage's call.⛔ Deliberately NOT folded into objectui#9326. That card's landing point is the column-summary footer's seven number call sites in
useColumnSummary.ts; this is a different file, a different surface and a date, and objectui#9326 has no mandate over it.The claim
formatImportJobTimeinpackages/plugin-grid/src/ImportWizard.tsxrenders an import-job timestamp with no locale argument at all:It feeds the import-job history table (
ImportHistoryPanel), which lists prior async import jobs with their status, counts and time.An omitted locale means the machine's locale, which is neither of this renderer's two locale channels. This is the contract
useDisplayLocale's own doc comment states, quoted verbatim:"Every date, number and currency renderer" — so a date renderer is inside the declared scope, not adjacent to it.
Why a date is not merely the same bug again
On a number the machine locale moves separators. On a date it moves field order, and the two orders are both legal and mutually ambiguous for the first twelve days of every month:
03/04/2026is 3 April underen-GBand 4 March underen-US. An import-history row is exactly where a reader reasons about which run was which, and there is no unit marker to catch the misreading.What it is not
ImportWizard.tsx.'—'empty fallback — that fallback is objectui#8507's subject, which names this same file for the em-dash class at a different line and says nothing about locale.ImportWizardhas an ergonomic path touseDisplayLocale()at this call site.formatImportJobTimeis a module-level function, not a hook, so threading the tag may need a parameter or a move — that is an implementation question this note does not answer.Dedup
Channel: repo-scoped REST issues list,
state=open,per_page=100, paged to exhaustion (pages 1-4 returned 100, page 5 returned 64, page 6 returned 0). Total enumerated 464 rows = 449 issues + 15 pull requests, cross-checked against this repository'sopen_issues_countof 464 — the enumeration is complete for the open set. Then a local title-and-body regex scan.Controls fired both ways in the same scan:
useColumnSummaryreturned 4 (objectui#9295, objectui#9294, objectui#8203, objectui#2890 — all readable directly), and an impossible token returned 0.Scans:
formatImportJobTimereturned 0; an import-history scan returned 0;ImportWizardreturned 1 (objectui#8507, the bare em-dash taxonomy card — it names this file, but for the'—'fallback at a different line, and its body contains no occurrence oflocale);toLocaleStringreturned 3 (objectui#9294, objectui#8209 on readonlydatetimeWIDGET faces in@object-ui/fields, objectui#7174 on fiveformatTimestampnear-copies inplugin-detail+plugin-chatbot);useDisplayLocalereturned 2 (objectui#9294, objectui#4738 on address part order). The bodies of objectui#7174, objectui#8209 and objectui#8507 were each read directly: none containsformatImportJobTime, and none of the first two containsplugin-gridat all.⛔ Boundary, stated rather than papered over: open issues only. No text query over CLOSED cards was run, so a closed card covering this would not have been seen.
Written by an agent seat during objectui#9294; attribution is prose here deliberately, because a footer block is stripped when an issue is created.