Skip to content

fix(widgets): ColumnChart runtime JSON.parse error — unset chart-series String emitted as \" \" - #5

Merged
ako merged 1 commit into
mainfrom
claude/mxbuild-diagnostics-spike-emta6h
Jul 21, 2026
Merged

fix(widgets): ColumnChart runtime JSON.parse error — unset chart-series String emitted as \" \"#5
ako merged 1 commit into
mainfrom
claude/mxbuild-diagnostics-spike-emta6h

Conversation

@ako

@ako ako commented Jul 21, 2026

Copy link
Copy Markdown
Owner

Summary

Fixes a runtime render failure on charts with a series/line object-list (e.g. ColumnChart). Follow-up to #4 (merged); this is the last residual from the widget-authoring testing round.

Symptom

A ColumnChart passed mx check (0 errors) but failed to render with a client-side JSON.parse('Unexpected end of JSON input') in the chart render path. A Pie chart over the same data (widget-level datasource, no series object-list) rendered fine.

Root cause

The object-list-item builder (createDefaultWidgetValue) emitted an unset String property as a single space " " instead of "". The chart client feeds customSeriesOptions / customLayout / customConfigurations straight to JSON.parse behind an empty-guard:

value !== "" ? value : "{}"

A lone space passes that guard (it isn't ""), so the client runs JSON.parse(" ") and throws. mx check never executes the client, so it stayed green. The Pie path went through the top-level String path, which already emitted "" — hence Pie rendered and Column didn't.

Fix

Leave an unset String empty (its schema default), matching Studio Pro and the top-level path, so the client's empty-guard turns it into "{}". The " " had no test and no justifying comment (the adjacent TextTemplate case already avoids a single-space value for the same class of reason).

Testing

  • Series customSeriesOptions is now "" (was " ") — zero space-valued primitives in the generated object.
  • mx check 0 errors; no CE0463 regression across the full chart example (all types), DataGrid2, and Gallery.
  • go test ./mdl/backend/... ./mdl/executor/... ./modelsdk/widgets/... ./sdk/widgets/... green.
  • Repro added: mdl-examples/bug-tests/chart-series-customseriesoptions-json.mdl.

🤖 Generated with Claude Code

https://claude.ai/code/session_01JXnEgoc2NQP1Y2TWMCMXC4


Generated by Claude Code

…time JSON.parse)

A ColumnChart with a static series passed mx check but failed to render with a
client-side JSON.parse('Unexpected end of JSON input'). The object-list-item
builder emitted an unset String property as a single space " " instead of "".
The chart client feeds customSeriesOptions / customLayout / customConfigurations
to JSON.parse behind an empty-guard (value !== "" ? value : "{}"); a lone
space passes that guard, so the client runs JSON.parse(" ") and throws. mx check
doesn't execute the client, so it stayed green. A Pie (widget-level datasource,
no series object-list) was unaffected — the top-level String path already emitted
"".

Leave an unset String empty, matching Studio Pro and the top-level path, so the
client's empty-guard turns it into "{}". Verified: series customSeriesOptions is
now "" (was " "), zero space-valued primitives; mx check 0 errors and no
CE0463 regression across charts / DataGrid2 / Gallery.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JXnEgoc2NQP1Y2TWMCMXC4
@ako
ako merged commit 2596c5f into main Jul 21, 2026
1 of 3 checks passed
ako pushed a commit that referenced this pull request Jul 27, 2026
Three checker hints steered authors the wrong way:

- MDL001 (nested loop) recommended `retrieve $Match from $List where …
  limit 1`, which is a parse error — a plain retrieve cannot filter a
  list variable. Recommend `$Match = FIND($List, <cond>)` (in-memory,
  O(N)). Same broken advice fixed in CLAUDE.md idiom #2.
- MDL044 flagged `count()` used in an expression with "Did you mean
  'round()'?" — count is an aggregate activity, not a typo. For the known
  aggregates (count/sum/average/minimum/maximum) emit "assign it to a
  variable first: $n = count($List);" instead of a did-you-mean.
- MDL044's generic hint cited `mxcli syntax expressions`, which does not
  exist; point it at `mxcli syntax microflow`.

Also lock in finding #5's second trigger: a microflow-call output
variable reused across a fallback chain (try A, else try B) is CE0111.
It was already caught by the shared create-output-variable check
(`check --references`); add TestValidateDuplicateMicroflowCallOutputVar
(same-scope + nested-in-if) as a regression guard and document the
correct pattern (one variable per call + a plain set) in
write-microflows.md.

Reported from the RSS-reader build (findings #7, #8, #14c, #5).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JXnEgoc2NQP1Y2TWMCMXC4
ako pushed a commit that referenced this pull request Jul 29, 2026
…c sugar, ADD doc (FINDINGS #3/#5/#13/#14/#4)

Five surprising parser rejects / silent-wrong writes where quoting or a keyword
behaved inconsistently with the rest of MDL:

- #3 index name can't be quoted: indexDefinition accepted only IDENTIFIER for the
  name → `index "idx_x" (Col)` was a parse error. Accept QUOTED_IDENTIFIER too
  (the name is advisory and discarded, as before).
- #5 role-name quoting inconsistent: DESCRIBE USER ROLE required quotes, DROP USER
  ROLE rejected them. Both now accept bare and quoted names; visitors handle both.
- #13 `sort by` quoted attribute stored a nonsense reference: a quoted qualified
  attribute (`sort by "Mod"."Entity"."Code"`) kept the quotes and only failed on
  write ("attribute does not belong to entity"). buildSortColumnMicroflow now
  unquotes each segment (bare dotted form), matching the SORT() list-op path.
- #14 `DataSource: ASSOCIATION $currentObject/…` didn't parse (keyword + sugar were
  mutually exclusive). Added the combined grammar branch; the existing
  VARIABLE&&SLASH visitor branch already handles it correctly.
- #4 doc: MDL spec README showed `alter entity … add (Attr: type)`, which the
  parser rejects. Corrected to `add attribute Attr: type`.

Grammar regenerated (`make grammar`). Verified end to end: quoted index name,
quoted qualified sort stored as `M.Thing.Code`, describe/drop role in both forms,
and `ASSOCIATION $currentObject/…` all parse/store correctly. Tests added.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JXnEgoc2NQP1Y2TWMCMXC4
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants