{"record":{"id":"5088c04cc3d49427","repo":"makeplane/plane","slug":"invalid-x-axis-field-x-axis","errorCode":null,"errorMessage":"Invalid x_axis field: {x_axis}","messagePattern":"Invalid x_axis field: (.+?)","errorType":"validation","errorClass":"ValidationError","httpStatus":null,"severity":"error","filePath":"apps/api/plane/utils/build_chart.py","lineNumber":161,"sourceCode":"    return [\n        {\n            \"key\": item[\"key\"] if item[\"key\"] else \"None\",\n            \"name\": item[\"display_name\"] if item[\"display_name\"] else \"None\",\n            \"count\": item[\"count\"],\n        }\n        for item in data\n    ]\n\n\ndef build_analytics_chart(\n    queryset: QuerySet[Issue],\n    x_axis: str,\n    group_by: Optional[str] = None,\n    date_filter: Optional[str] = None,\n) -> Dict[str, Union[List[Dict[str, Any]], Dict[str, str]]]:\n    # Validate x_axis\n    if x_axis not in x_axis_mapper:\n        raise ValidationError(f\"Invalid x_axis field: {x_axis}\")\n\n    # Validate group_by\n    if group_by and group_by not in x_axis_mapper:\n        raise ValidationError(f\"Invalid group_by field: {group_by}\")\n\n    field_mapping = get_x_axis_field()\n\n    id_field, name_field, additional_filter = field_mapping.get(x_axis, (None, None, {}))\n    group_field, group_name_field, group_additional_filter = field_mapping.get(group_by, (None, None, {}))\n\n    # Apply additional filters if they exist\n    if additional_filter or {}:\n        queryset = queryset.filter(**additional_filter)\n\n    if group_additional_filter or {}:\n        queryset = queryset.filter(**group_additional_filter)\n\n    aggregate_func = Count(\"id\", distinct=True)","sourceCodeStart":143,"sourceCodeEnd":179,"githubUrl":"https://github.com/makeplane/plane/blob/1c8a60f858d8472aa56e29994ec1c7926da2c6ce/apps/api/plane/utils/build_chart.py#L143-L179","documentation":"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.","triggerScenarios":"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.","commonSituations":"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'.","solutions":["Pass one of the 13 UPPERCASE x_axis_mapper keys exactly (e.g. 'STATES', 'PRIORITY', 'CREATED_AT').","Do not pass analytics_plot's lowercase fields (state_id, priority) to build_analytics_chart - they will be rejected.","Strip whitespace and uppercase the input if it comes from user/URL input: `x_axis = x_axis.strip().upper()`.","Import x_axis_mapper and assert `x_axis in x_axis_mapper` before calling."],"exampleFix":"# before\nbuild_analytics_chart(qs, x_axis=\"state_id\")\nbuild_analytics_chart(qs, x_axis=\"priority\")\n\n# after\nbuild_analytics_chart(qs, x_axis=\"STATES\")\nbuild_analytics_chart(qs, x_axis=\"PRIORITY\")","handlingStrategy":"validation","validationCode":"from plane.utils.build_chart import x_axis_mapper, build_analytics_chart\n\ndef is_valid_chart_x_axis(x_axis: str) -> bool:\n    # build_chart expects UPPERCASE keys, unlike analytics_plot\n    return x_axis in x_axis_mapper","typeGuard":"from plane.utils.build_chart import x_axis_mapper\n\ndef is_valid_chart_x_axis(value: str) -> bool:\n    return isinstance(value, str) and value in x_axis_mapper","tryCatchPattern":"from django.core.exceptions import ValidationError\ntry:\n    build_analytics_chart(qs, x_axis, group_by)\nexcept ValidationError as e:\n    if 'Invalid x_axis field' in str(e):\n        return bad_request(str(e))","preventionTips":["Pass UPPERCASE category labels (STATES, PRIORITY, CREATED_AT, ...) to build_chart.","Do NOT pass analytics_plot's lowercase field names here.","Normalize URL/user input: value.strip().upper()."],"tags":["analytics","validation","chart","api"],"backgroundTag":null,"analyzedSha":"1c8a60f858d8472aa56e29994ec1c7926da2c6ce","analyzedAt":"2026-08-12T14:44:31.636Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}