makeplane/plane · error · ValueError
Invalid x_axis value: {x_axis}
Error message
Invalid x_axis value: {x_axis} What it means
ValueError raised by `extract_axis` (analytics_plot.py:54) when `x_axis` is not in `VALID_ANALYTICS_FIELDS` - the lowercase allow-list: state_id, state__group, labels__id, assignees__id, estimate_point__value, issue_cycle__cycle_id, issue_module__module_id, priority, start_date, target_date, created_at, completed_at. Note this list uses different (lowercase) keys than build_chart.py's x_axis_mapper (UPPERCASE), a common source of confusion.
Source
Thrown at apps/api/plane/utils/analytics_plot.py:55
"completed_at",
]
VALID_YAXIS = ["issue_count", "estimate"]
def annotate_with_monthly_dimension(queryset, field_name, attribute):
# Get the year and the months
year = ExtractYear(field_name)
month = ExtractMonth(field_name)
# Concat the year and month
dimension = Concat(year, Value("-"), month, output_field=CharField())
# Annotate the dimension
return queryset.annotate(**{attribute: dimension})
def extract_axis(queryset, x_axis):
if x_axis not in VALID_ANALYTICS_FIELDS:
raise ValueError(f"Invalid x_axis value: {x_axis}")
# Format the dimension when the axis is in date
if x_axis in ["created_at", "start_date", "target_date", "completed_at"]:
queryset = annotate_with_monthly_dimension(queryset, x_axis, "dimension")
return queryset, "dimension"
else:
return queryset.annotate(dimension=F(x_axis)), "dimension"
def sort_data(data, temp_axis):
# When the axis is in priority order by
if temp_axis == "priority":
order = ["low", "medium", "high", "urgent", "none"]
return {key: data[key] for key in order if key in data}
else:
return dict(sorted(data.items(), key=lambda x: (x[0] == "none", x[0])))
def build_graph_plot(queryset, x_axis, y_axis, segment=None):View on GitHub (pinned to 1c8a60f858)
Solutions
- Pass one of the 12 VALID_ANALYTICS_FIELDS values exactly (lowercase, with the trailing __id / __group where applicable).
- If integrating with build_chart code that uses UPPERCASE keys, map them down to the lowercase analytics fields before calling extract_axis.
- For the HTTP endpoint, prefer the endpoint's own 400 validation message; reserve direct extract_axis calls for validated inputs.
- Add a constant import (`from plane.utils.analytics_plot import VALID_ANALYTICS_FIELDS`) and assert membership before calling.
Example fix
# before extract_axis(qs, "STATES") # not in lowercase list extract_axis(qs, "state") # wrong - needs state_id # after extract_axis(qs, "state_id")
Defensive patterns
Strategy: validation
Validate before calling
from plane.utils.analytics_plot import VALID_ANALYTICS_FIELDS
def is_valid_x_axis(x_axis: str) -> bool:
# mirrors analytics_plot.py:54 check
return x_axis in VALID_ANALYTICS_FIELDS Type guard
from plane.utils.analytics_plot import VALID_ANALYTICS_FIELDS
def is_valid_analytics_field(value: str) -> bool:
"""Narrow a string to a known analytics x_axis/segment value."""
return isinstance(value, str) and value in VALID_ANALYTICS_FIELDS Prevention
- Validate x_axis against VALID_ANALYTICS_FIELDS before calling extract_axis.
- Remember these are lowercase field names; build_chart uses UPPERCASE labels.
- Import the constant rather than re-hardcoding the list.
When it happens
Trigger: Calling `extract_axis(queryset, x_axis)` directly, or hitting a code path that reaches it without prior validation, with an x_axis outside the 12-field allow-list (e.g. 'state', 'assignees', 'ESTATE', or a typo). The HTTP AnalyticsEndpoint validates first, so this fires mainly via internal callers like the bgtask analytic_plot_export.
Common situations: Backend bgtasks/tests calling extract_axis with the UPPERCASE keys from build_chart's x_axis_mapper; passing a related-field name like 'state' instead of 'state_id'; copy-paste from the chart API which expects different casing.
Related errors
- Invalid y_axis value: {y_axis}
- Invalid segment value: {segment}
- Invalid x_axis field: {x_axis}
- Invalid group_by field: {group_by}
- Unsupported format: {format_type}. Available: {list(self.FOR
AI-assisted analysis of makeplane/plane@1c8a60f858 (2026-08-12).
Data as JSON: /api/errors/c3e94b50d48ef599.
Report an issue: GitHub.