apache/superset · error · Error
Found invalid orderby options
Error message
Found invalid orderby options
What it means
Raised by masked_encrypted_extra_validator (superset/databases/schemas.py:260) when the masked_encrypted_extra field is exactly the string "{}". This field round-trips the masked (redacted) form of encrypted_extra in Database API responses; submitting back an empty object means 'no change requested', which Superset rejects as an empty update rather than silently wiping the stored secrets.
Source
Thrown at superset-frontend/packages/superset-ui-core/src/query/extractQueryFields.ts:121
return {
columns: removeDuplicates(
columns.filter(col => col !== ''),
getColumnLabel,
),
metrics:
queryMode === QueryMode.Raw
? undefined
: removeDuplicates(metrics, getMetricLabel),
orderby:
orderby.length > 0
? orderby.map(item => {
// value can be in the format of `['["col1", true]', '["col2", false]'],
// where the option strings come directly from `order_by_choices`.
if (typeof item === 'string') {
try {
return JSON.parse(item);
} catch (error) {
throw new Error(t('Found invalid orderby options'));
}
}
return item;
})
: undefined,
};
}
View on GitHub (pinned to f4587218dd)
Solutions
- Omit masked_encrypted_extra from the PUT payload when you do not intend to change it
- Send null instead of "{}" when you want to clear or skip the field
- Only send masked_encrypted_extra when replacing secrets, and send real JSON with content
Example fix
# before
body = {**db_response, "masked_encrypted_extra": "{}"} # 400 Field cannot be empty.
# after
body = {k: v for k, v in db_response.items() if k != "masked_encrypted_extra"} Defensive patterns
Strategy: validation
Validate before calling
def clean_masked(d: dict) -> dict:
me = d.get("masked_encrypted_extra")
if me is not None and (me == "{}" or not me.strip()):
d.pop("masked_encrypted_extra", None)
return d Type guard
const hasMaskedExtra = (b: Record<string, unknown>): boolean =>
typeof b.masked_encrypted_extra === "string" && b.masked_encrypted_extra.trim() !== "{}" && b.masked_encrypted_extra.trim() !== ""; Prevention
- Never echo masked_encrypted_extra from a GET back into a PUT
- Treat masked_encrypted_extra as write-only: include it only when deliberately replacing secrets
When it happens
Trigger: PUT /api/v1/database/<id> where the client echoes the masked value it previously read, but the database has no encrypted_extra so the masked form is "{}"; or a client that always includes masked_encrypted_extra in the payload, even when empty.
Common situations: Automation that GETs a database, mutates unrelated fields, and PUTs the whole object back including masked_encrypted_extra: "{}". Also forms with a hidden encrypted-extra input defaulting to "{}".
Related errors
- Unsupported whisker type: ${whiskerOptions}
- Unknown Error
- Please provide both time bounds (Since and Until)
- All values must be numeric
- validation_error
AI-assisted analysis of apache/superset@f4587218dd (2026-08-14).
Data as JSON: /api/errors/0c71bc4d8644ce7c.
Report an issue: GitHub.