apache/superset · error
Invalid JSON string: ${String(error)}
Error message
Invalid JSON string: ${String(error)} What it means
The parseJson Handlebars helper (Handlebars chart plugin) wraps JSON.parse and rethrows with a prefixed message when the template passes a string that is not valid JSON. The original parse error text is preserved so the offending position in the string is visible.
Source
Thrown at superset-frontend/plugins/plugin-chart-handlebars/src/components/Handlebars/HandlebarsViewer.tsx:113
'formatNumber',
function (number: any, locale = 'en-US') {
if (typeof number !== 'number') {
return number;
}
return number.toLocaleString(locale);
},
);
// usage: {{parseJson jsonString}}
Handlebars.registerHelper('parseJson', (jsonString: string) => {
try {
return JSON.parse(jsonString);
} catch (error) {
if (error instanceof Error) {
error.message = `Invalid JSON string: ${error.message}`;
throw error;
}
throw new Error(`Invalid JSON string: ${String(error)}`);
}
});
Helpers.registerHelpers(Handlebars);
HandlebarsGroupBy.register(Handlebars);
// `just-handlebars-helpers` registers a `formatDate` helper that lazily
// resolves `moment` via `global.moment` / `require('moment/min/moment-with-locales')`.
// The bundled viewer switched to dayjs and never satisfies that lookup, so the
// original helper throws "... is not a function" (see #32960). Re-register a
// dayjs-backed `formatDate` with the same `{{formatDate formatString date [locale]}}`
// signature so existing templates keep rendering.
Handlebars.registerHelper('formatDate', (formatString, date, localeString) => {
const format = typeof formatString === 'string' ? formatString : '';
const instance = dayjs(date ?? new Date());
// Handlebars always passes its options object as the final argument, so a
// locale is only present when the caller supplied an explicit string.
// Note: `extendedDayjs` only loads the `en` locale, so passing a non-EnglishView on GitHub (pinned to f4587218dd)
Solutions
- Validate/clean the JSON column at the data source (CHECK constraints, backfill repairs).
- Guard in the template: {{#if jsonString}}{{parseJson jsonString}}{{/if}} to skip nulls.
- If the driver already returns objects, remove the parseJson call and use the field directly.
- Inspect the failing row in SQL Lab to find the exact malformed value and position from the message.
Example fix
{{! before }}
{{parseJson data.meta}}
{{! after }}
{{#if data.meta}}
{{#if (isString data.meta)}}{{parseJson data.meta}}{{else}}{{stringify data.meta}}{{/if}}
{{/if}} Defensive patterns
Strategy: validation
Validate before calling
function isJsonString(v: unknown): v is string {
if (typeof v !== 'string') return false;
try {
JSON.parse(v);
return true;
} catch {
return false;
}
} Type guard
function isParsableJson(v: unknown): v is string {
return typeof v === 'string' && (() => { try { JSON.parse(v); return true; } catch { return false; } })();
} Try / catch
{{#if (isJsonString data.meta)}}
{{parseJson data.meta}}
{{else}}
{{data.meta}}
{{/if}} Prevention
- Constrain JSON columns at the database level and repair bad rows before visualizing them.
- Skip parseJson when the driver already returns parsed objects.
- Log the raw failing string length/snippet when templates error to speed up data fixes.
When it happens
Trigger: Template uses {{parseJson jsonString}} where jsonString is a column containing malformed JSON, a number, null, or a value already parsed to an object (stringified twice / not stringified at all).
Common situations: Database column stores truncated or hand-edited JSON; NULL values reaching the helper; column is JSON-typed and the driver already returns an object, so JSON.parse receives '[object Object]'.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Please call with an object. Example: `stringify myObj`
- Unsupported whisker type: ${whiskerOptions}
- Unknown Error
- parse_error
- JSON not valid
AI-assisted analysis of apache/superset@f4587218dd (2026-08-14).
Data as JSON: /api/errors/9e97ed0ba7adfcbd.
Report an issue: GitHub.