apache/superset · error · ValidationError

Request is incorrect

Error message

Request is incorrect

What it means

ValidationError('Request is incorrect') raised in ChartDataRestApi._run_create_query_context: loading the request payload through ChartDataQueryContextSchema raises a KeyError (typically from custom pre_load/field logic touching a dict key the payload does not contain, e.g. missing 'datasource' or a form_data sub-key), and the handler converts it into a generic 'Request is incorrect' validation error. It signals the form_data structure does not match what the chart-data API expects.

Source

Thrown at superset/charts/data/api.py:725

            "slice_id": form_data.get("form_data", {}).get("slice_id"),
        }

    @logs_context(context_func=_map_form_data_datasource_to_dataset_id)
    def _create_query_context_from_form(
        self, form_data: dict[str, Any]
    ) -> QueryContext:
        """
        Create the query context from the form data.

        :param form_data: The chart form data
        :returns: The query context
        :raises ValidationError: If the request is incorrect
        """

        try:
            return ChartDataQueryContextSchema().load(form_data)
        except KeyError as ex:
            raise ValidationError("Request is incorrect") from ex

    def _should_use_streaming(
        self, result: dict[Any, Any], form_data: dict[str, Any] | None = None
    ) -> bool:
        """Determine if streaming should be used based on actual row count threshold."""
        query_context = result["query_context"]
        result_format = query_context.result_format

        # Only support CSV streaming currently
        if result_format.lower() != "csv":
            return False

        # Get streaming threshold from config
        threshold = app.config.get("CSV_STREAMING_ROW_THRESHOLD", 100000)

        # Extract actual row count (same logic as frontend)
        actual_row_count: int | None = None
        viz_type = form_data.get("viz_type") if form_data else None

View on GitHub (pinned to f4587218dd)

Solutions

  1. Capture a working payload from the Explore UI (browser devtools, network tab) for the same chart and diff it against yours to find the missing key.
  2. Ensure the payload contains 'datasource' (id + type) and a valid 'queries' array with all required fields per ChartDataQueryContextSchema.
  3. If you only have classic form_data, send it under the documented form_data key so the schema's pre_load normalizes it.
  4. Wrap the call and log the full rejected payload server-side (the original KeyError is chained via `from ex`) to identify the exact missing key.

Example fix

# before
requests.post("/api/v1/chart/data", json={
    "queries": [{"metrics": ["COUNT"]}],   # no datasource -> KeyError -> Request is incorrect
})

# after
requests.post("/api/v1/chart/data", json={
    "datasource": {"id": 1, "type": "table"},
    "queries": [{"metrics": ["COUNT(*)"], "granularity": None, "groupby": [], "filters": [], "row_limit": 100}],
})
Defensive patterns

Strategy: validation

Validate before calling

def payload_is_queryable(p: dict) -> bool:
    datasource = p.get("datasource")
    queries = p.get("queries")
    return (
        isinstance(datasource, dict)
        and {"id", "type"} <= datasource.keys()
        and isinstance(queries, list)
        and len(queries) > 0
    )

assert payload_is_queryable(payload)

Try / catch

from marshmallow import ValidationError
try:
    resp = post_chart_data(payload)
except ValidationError as ex:
    if "Request is incorrect" in str(ex):
        log.error("rejected payload: %s", json.dumps(payload))  # diff vs a UI-captured payload\n        raise

Prevention

When it happens

Trigger: POST /api/v1/chart/data with a payload missing required top-level keys such as 'datasource', 'queries' (or 'form_data' when using that shape), or with form_data whose nested keys (e.g. slice_id, datasource_id/datasource_name) are absent. Programmatic callers building payloads by hand instead of copying the shape the Explore UI sends are the usual source.

Common situations: Scripts that POST a minimal {'query': ...} payload assuming server-side defaults; frontend code paths that strip form_data keys; migrating clients from an older chart-data payload schema; embedding chart data calls where the payload was JSON-serialized from a partial object.

Related errors


AI-assisted analysis of apache/superset@f4587218dd (2026-08-14). Data as JSON: /api/errors/a612b798bd795d25. Report an issue: GitHub.