makeplane/plane · error · ValidationError

Invalid x_axis field: {x_axis}

Error message

Invalid x_axis field: {x_axis}

What it means

Django ValidationError raised by `build_analytics_chart` (build_chart.py:161) when `x_axis` is not a key of `x_axis_mapper`. Unlike analytics_plot.py, this mapper uses UPPERCASE keys: STATES, STATE_GROUPS, LABELS, ASSIGNEES, ESTIMATE_POINTS, CYCLES, MODULES, PRIORITY, START_DATE, TARGET_DATE, CREATED_AT, COMPLETED_AT, CREATED_BY. Passing a lowercase field name triggers the error.

Source

Thrown at apps/api/plane/utils/build_chart.py:161

    return [
        {
            "key": item["key"] if item["key"] else "None",
            "name": item["display_name"] if item["display_name"] else "None",
            "count": item["count"],
        }
        for item in data
    ]


def build_analytics_chart(
    queryset: QuerySet[Issue],
    x_axis: str,
    group_by: Optional[str] = None,
    date_filter: Optional[str] = None,
) -> Dict[str, Union[List[Dict[str, Any]], Dict[str, str]]]:
    # Validate x_axis
    if x_axis not in x_axis_mapper:
        raise ValidationError(f"Invalid x_axis field: {x_axis}")

    # Validate group_by
    if group_by and group_by not in x_axis_mapper:
        raise ValidationError(f"Invalid group_by field: {group_by}")

    field_mapping = get_x_axis_field()

    id_field, name_field, additional_filter = field_mapping.get(x_axis, (None, None, {}))
    group_field, group_name_field, group_additional_filter = field_mapping.get(group_by, (None, None, {}))

    # Apply additional filters if they exist
    if additional_filter or {}:
        queryset = queryset.filter(**additional_filter)

    if group_additional_filter or {}:
        queryset = queryset.filter(**group_additional_filter)

    aggregate_func = Count("id", distinct=True)

View on GitHub (pinned to 1c8a60f858)

Solutions

  1. Pass one of the 13 UPPERCASE x_axis_mapper keys exactly (e.g. 'STATES', 'PRIORITY', 'CREATED_AT').
  2. Do not pass analytics_plot's lowercase fields (state_id, priority) to build_analytics_chart - they will be rejected.
  3. Strip whitespace and uppercase the input if it comes from user/URL input: `x_axis = x_axis.strip().upper()`.
  4. Import x_axis_mapper and assert `x_axis in x_axis_mapper` before calling.

Example fix

# before
build_analytics_chart(qs, x_axis="state_id")
build_analytics_chart(qs, x_axis="priority")

# after
build_analytics_chart(qs, x_axis="STATES")
build_analytics_chart(qs, x_axis="PRIORITY")
Defensive patterns

Strategy: validation

Validate before calling

from plane.utils.build_chart import x_axis_mapper, build_analytics_chart

def is_valid_chart_x_axis(x_axis: str) -> bool:
    # build_chart expects UPPERCASE keys, unlike analytics_plot
    return x_axis in x_axis_mapper

Type guard

from plane.utils.build_chart import x_axis_mapper

def is_valid_chart_x_axis(value: str) -> bool:
    return isinstance(value, str) and value in x_axis_mapper

Try / catch

from django.core.exceptions import ValidationError
try:
    build_analytics_chart(qs, x_axis, group_by)
except ValidationError as e:
    if 'Invalid x_axis field' in str(e):
        return bad_request(str(e))

Prevention

When it happens

Trigger: Calling build_analytics_chart with an x_axis not exactly matching one of the 13 UPPERCASE x_axis_mapper keys - e.g. 'state', 'state_id', 'priority' (lowercase), or any value from analytics_plot's lowercase VALID_ANALYTICS_FIELDS.

Common situations: Developers mixing up the two analytics utilities: analytics_plot expects lowercase field names, build_chart expects UPPERCASE category labels; passing a raw ORM field name instead of the category label; whitespace/typos like ' PRIORITY'.

Related errors


AI-assisted analysis of makeplane/plane@1c8a60f858 (2026-08-12). Data as JSON: /api/errors/5088c04cc3d49427. Report an issue: GitHub.