apache/superset · error · EChartOptionsParseError
parse_error
parse_error
Error message
err.message
What it means
Raised in SlackV1Upgrade.update_recipients when json.loads(recipient.recipient_config_json) throws TypeError or ValueError for a Slack v1 recipient: the stored recipient_config_json column is not parseable JSON (or not a string at all). It aborts the v1→v2 Slack recipient migration before any writes, so recipients remain untouched.
Source
Thrown at superset-frontend/plugins/plugin-chart-echarts/src/utils/safeEChartOptionsParser.ts:421
}
const trimmed = input.trim();
if (!trimmed) {
return { success: true, data: undefined };
}
// Step 1: Parse into AST
const wrappedInput = `(${trimmed})`;
let ast: Node & { body: Array<Node & { expression: Node }> };
try {
ast = parse(wrappedInput, {
ecmaVersion: 2020,
sourceType: 'script',
}) as Node & { body: Array<Node & { expression: Node }> };
} catch (error) {
const err = error as Error & { loc?: { line: number; column: number } };
throw new EChartOptionsParseError(err.message, 'parse_error', [], err.loc);
}
if (
!ast.body ||
ast.body.length !== 1 ||
ast.body[0].type !== 'ExpressionStatement'
) {
throw new EChartOptionsParseError(
'Input must be a single object literal expression (e.g., { key: value })',
'parse_error',
);
}
const { expression } = ast.body[0];
if (expression.type !== 'ObjectExpression') {
throw new EChartOptionsParseError(
`Expected an object literal, but got: ${expression.type}`,View on GitHub (pinned to f4587218dd)
Solutions
- Inspect the row: SELECT id, recipient_config_json FROM report_recipient WHERE id = <id>.
- Repair the JSON to a valid object with a string 'target' field (or recreate the recipient via the UI).
- Re-run the report; the migration will retry the upgrade.
Example fix
-- before: invalid JSON stored
UPDATE report_recipient SET recipient_config_json = '{"target":"#general"}' WHERE id = 7;
-- (was: '{target:#general}' — unquoted keys) Defensive patterns
Strategy: validation
Validate before calling
import json
def valid_recipient_json(cfg: str) -> bool:
try:
json.loads(cfg)
return True
except (TypeError, ValueError):
return False Type guard
def is_slack_v1_config(value: str) -> bool:
try:
parsed = json.loads(value)
except (TypeError, ValueError):
return False
return isinstance(parsed, dict) and isinstance(parsed.get("target"), str) Try / catch
try:
command.run()
except NotificationParamException as ex:
if "Invalid Slack recipient configuration" in str(ex):
flag_recipient_row_for_repair(recipient_id) Prevention
- Always create Slack recipients through the Superset UI/API, never SQL.
- Run a periodic JSON-validity check on report_recipient.recipient_config_json.
When it happens
Trigger: Executing a report with a Slack (v1) recipient whose recipient_config_json holds malformed JSON — hand-edited rows, legacy truncated data, or rows written by an old buggy client. json.loads raises ValueError (bad JSON) or TypeError (None/non-str).
Common situations: Direct DB edits to report_recipient rows; data migrated from a very old Superset version with a different config shape; JSON containing unescaped quotes truncated by column limits.
Related errors
- Please choose at least one groupby
- Unsupported whisker type: ${whiskerOptions}
- Unknown Error
- Invalid JSON string: ${String(error)}
- JSON not valid
AI-assisted analysis of apache/superset@f4587218dd (2026-08-14).
Data as JSON: /api/errors/88df90db68ab970e.
Report an issue: GitHub.