Skip to content

fix(callbacks): use . for dots in dict ID callback IDs to fix JSON.parse SyntaxError - #3923

Open
Mukller wants to merge 1 commit into
plotly:devfrom
Mukller:fix/dict-id-dot-escape
Open

fix(callbacks): use . for dots in dict ID callback IDs to fix JSON.parse SyntaxError#3923
Mukller wants to merge 1 commit into
plotly:devfrom
Mukller:fix/dict-id-dot-escape

Conversation

@Mukller

@Mukller Mukller commented Jul 29, 2026

Copy link
Copy Markdown

Problem

Fixes #3480.

When a dict component ID contains a dot in one of its string values (e.g.
id={"component": "button.dot"}), opening the app results in a blank page and
SyntaxError: Bad escaped character in JSON in the browser console.

Root cause

In _utils.py, create_callback_id calls x.component_id_str().replace(".", ".")
on every component ID. For string IDs this is fine, but dict IDs are serialized
as JSON. After the replacement, a value like "button.dot" becomes "button.dot"
inside the JSON fragment. The frontend then calls JSON.parse on this fragment
(in parsePMCId and callbacks.ts) and encounters . which is NOT a valid JSON
escape sequence -> SyntaxError.

Fix

For dict IDs, replace . with . (the standard JSON Unicode escape for
U+002E FULL STOP) instead of .:

  • . is valid inside a JSON string.
  • JSON.parse transparently decodes it back to ., so the frontend receives
    the original dict value unchanged.
  • No changes are needed on the JavaScript side.

Before / After

component_id = {"component": "button.dot"}, property = "children"

Before (broken): {"component":"button.dot"}.children
-> JSON.parse throws SyntaxError

After (fixed): {"component":"button.dot"}.children
-> JSON.parse returns {"component": "button.dot"} correctly

Closes #3480.

@Mukller Mukller left a comment

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Self-Review

Root Cause

escapes dots in component IDs with so they don't collide
with the separator between component-id and property in the callback ID string.
This is correct for string IDs (the JS side un-escapes when splitting).

For dict IDs, returns valid JSON (e.g.
). After , the dot inside
the JSON string value becomes — an invalid JSON escape sequence — and
throws .

Why is the right fix

is a standard JSON Unicode escape (U+002E FULL STOP). It is
valid inside JSON strings and decodes it back to automatically.
The frontend receives the original dict value unchanged. No JS changes are needed.

Correctness matrix

ID type Value Callback ID (before) Callback ID (after)
string unchanged
dict — BROKEN
dict multi-dot — BROKEN
dict, no dot unchanged unchanged

What does NOT change

  • — unchanged; still used for runtime input matching
  • Pattern-matching wildcards (//) — no dots → unaffected
  • Multi-output format () — structural separators unaffected
  • — still ; callers that parse the JSON portion
    use which correctly decodes →
  • No JavaScript changes required — handles natively

@sonarqubecloud

Copy link
Copy Markdown

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.

[BUG] Error when using . in dict ids

1 participant