apache/superset · error · SupersetApiError
Unknown Error
Error message
Unknown Error
What it means
Raised by extra_validator (superset/databases/schemas.py:273) when the Database API extra field is non-empty but not parseable JSON. extra carries connection tuning options (engine_params, metadata_params, schema_cache_timeout, etc.) as a JSON string; marshmallow validation fails with HTTP 400 and the underlying json.JSONDecodeError message before any DB engine is constructed.
Source
Thrown at superset-frontend/packages/superset-ui-core/src/query/api/v1/handleError.ts:42
export type ErrorInput = string | Error | Response | SupersetApiErrorPayload;
/**
* Handle API request errors, convert to consistent Superset API error.
* @param error the catched error from SupersetClient.request(...)
*/
export default async function handleError(error: ErrorInput): Promise<never> {
// already a Superset error
if (error instanceof SupersetApiError) {
throw error;
}
// string is the error message itself
if (typeof error === 'string') {
throw new SupersetApiError({ message: error });
}
// JS errors, normally happens before request was sent
if (error instanceof Error) {
throw new SupersetApiError({
message: error.message || 'Unknown Error',
originalError: error,
});
}
let errorJson;
let originalError;
let errorMessage = 'Unknown Error';
let status: number | undefined;
let statusText: string | undefined;
// catch HTTP errors
if (error instanceof Response) {
const { status: responseStatus, statusText: responseStatusText } = error;
status = responseStatus;
statusText = responseStatusText;
errorMessage = `${status} ${statusText}`;
try {View on GitHub (pinned to f4587218dd)
Solutions
- Build extra as a dict and serialize with json.dumps() instead of string concatenation or repr()
- Lint the payload locally: json.loads(extra) must succeed before sending
- Check the error's %(msg)s detail — it names the line/column of the first JSON syntax error
Example fix
// before (frontend)
body.extra = `{ engine_params: { pool_size: 5 } }`; // unquoted keys -> 400
// after
body.extra = JSON.stringify({ engine_params: { pool_size: 5 } }); Defensive patterns
Strategy: validation
Validate before calling
import json
extra_obj = {"engine_params": {"pool_size": 5}}
payload["extra"] = json.dumps(extra_obj) # never hand-built strings
json.loads(payload["extra"]) # assert round-trip Type guard
function isExtraJson(extra: string): boolean {
try { JSON.parse(extra); return true; } catch { return false; }
} Try / catch
if resp.status_code == 400 and "cannot be decoded by JSON" in resp.text:
# resp body carries the JSONDecodeError position; fix the payload at that offset Prevention
- Construct extra as a dict and serialize once
- Beware NaN/Infinity and single quotes — valid Python literals, invalid JSON
- After upgrades, re-read the Database API schema for extra key changes
When it happens
Trigger: POST/PUT /api/v1/database with extra built via Python repr or f-string templating that breaks quoting; extra containing NaN/Infinity literals (invalid JSON); copy-pasting the YAML form of extra from superset config docs directly into the API payload.
Common situations: Converting a config-file TSQL/CATALOGS-style extra dict to the REST API format and forgetting json.dumps; injecting secrets into extra via string concatenation that leaves unescaped quotes; version upgrades where extra keys changed shape and scripts send hand-built JSON strings.
Related errors
- Unsupported whisker type: ${whiskerOptions}
- Found invalid orderby options
- JSON not valid
- Please provide both time bounds (Since and Until)
- All values must be numeric
AI-assisted analysis of apache/superset@f4587218dd (2026-08-14).
Data as JSON: /api/errors/c083a00820f7bb34.
Report an issue: GitHub.