{"record":{"id":"9e97ed0ba7adfcbd","repo":"apache/superset","slug":"invalid-json-string-string-error","errorCode":null,"errorMessage":"Invalid JSON string: ${String(error)}","messagePattern":"Invalid JSON string: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"superset-frontend/plugins/plugin-chart-handlebars/src/components/Handlebars/HandlebarsViewer.tsx","lineNumber":113,"sourceCode":"  'formatNumber',\n  function (number: any, locale = 'en-US') {\n    if (typeof number !== 'number') {\n      return number;\n    }\n    return number.toLocaleString(locale);\n  },\n);\n\n// usage: {{parseJson jsonString}}\nHandlebars.registerHelper('parseJson', (jsonString: string) => {\n  try {\n    return JSON.parse(jsonString);\n  } catch (error) {\n    if (error instanceof Error) {\n      error.message = `Invalid JSON string: ${error.message}`;\n      throw error;\n    }\n    throw new Error(`Invalid JSON string: ${String(error)}`);\n  }\n});\n\nHelpers.registerHelpers(Handlebars);\nHandlebarsGroupBy.register(Handlebars);\n\n// `just-handlebars-helpers` registers a `formatDate` helper that lazily\n// resolves `moment` via `global.moment` / `require('moment/min/moment-with-locales')`.\n// The bundled viewer switched to dayjs and never satisfies that lookup, so the\n// original helper throws \"... is not a function\" (see #32960). Re-register a\n// dayjs-backed `formatDate` with the same `{{formatDate formatString date [locale]}}`\n// signature so existing templates keep rendering.\nHandlebars.registerHelper('formatDate', (formatString, date, localeString) => {\n  const format = typeof formatString === 'string' ? formatString : '';\n  const instance = dayjs(date ?? new Date());\n  // Handlebars always passes its options object as the final argument, so a\n  // locale is only present when the caller supplied an explicit string.\n  // Note: `extendedDayjs` only loads the `en` locale, so passing a non-English","sourceCodeStart":95,"sourceCodeEnd":131,"githubUrl":"https://github.com/apache/superset/blob/f4587218dd19d046c3e4d00063e7d27f8a2ed354/superset-frontend/plugins/plugin-chart-handlebars/src/components/Handlebars/HandlebarsViewer.tsx#L95-L131","documentation":"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.","triggerScenarios":"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).","commonSituations":"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]'.","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."],"exampleFix":"{{! before }}\n{{parseJson data.meta}}\n\n{{! after }}\n{{#if data.meta}}\n  {{#if (isString data.meta)}}{{parseJson data.meta}}{{else}}{{stringify data.meta}}{{/if}}\n{{/if}}","handlingStrategy":"validation","validationCode":"function isJsonString(v: unknown): v is string {\n  if (typeof v !== 'string') return false;\n  try {\n    JSON.parse(v);\n    return true;\n  } catch {\n    return false;\n  }\n}","typeGuard":"function isParsableJson(v: unknown): v is string {\n  return typeof v === 'string' && (() => { try { JSON.parse(v); return true; } catch { return false; } })();\n}","tryCatchPattern":"{{#if (isJsonString data.meta)}}\n  {{parseJson data.meta}}\n{{else}}\n  {{data.meta}}\n{{/if}}","preventionTips":["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."],"tags":["handlebars","json","template","chart-plugin"],"backgroundTag":null,"analyzedSha":"f4587218dd19d046c3e4d00063e7d27f8a2ed354","analyzedAt":"2026-08-14T22:39:27.425Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}