apache/superset · error · AnnotationInvalidError
Annotation parameters are invalid.
Error message
Annotation parameters are invalid.
What it means
AnnotationInvalidError (CommandInvalidError, HTTP 422) raised at the end of AnnotationCreateCommand.validate() when the per-field validation list is non-empty. Two checks feed the list: AnnotationUniquenessValidationError (short_descr already used on that layer) and AnnotationDatesValidationError (end_dttm earlier than start_dttm). The raised error carries the list of Marshmallow ValidationErrors in _exceptions so the API can return field-level details.
Source
Thrown at superset/commands/annotation_layer/annotation/create.py:72
# Validate/populate model exists
if not layer_id and not isinstance(layer_id, int):
raise AnnotationLayerNotFoundError()
annotation_layer = AnnotationLayerDAO.find_by_id(layer_id)
if not annotation_layer:
raise AnnotationLayerNotFoundError()
self._properties["layer"] = annotation_layer
# Validate short descr uniqueness on this layer
if not AnnotationDAO.validate_update_uniqueness(layer_id, short_descr):
exceptions.append(AnnotationUniquenessValidationError())
# validate date time sanity
if start_dttm and end_dttm and end_dttm < start_dttm:
exceptions.append(AnnotationDatesValidationError())
if exceptions:
raise AnnotationInvalidError(exceptions=exceptions)
View on GitHub (pinned to f4587218dd)
Solutions
- Check uniqueness first: GET /api/v1/annotation/?q=(layer:<id>,short_descr:eq:<value>) and reuse or rename.
- Normalize start_dttm/end_dttm to the same timezone (UTC) and assert end >= start before sending.
- Read error._exceptions for field-level messages to know which validation failed.
Example fix
# before
{"layer": 1, "short_descr": "launch", "start_dttm": "2026-03-02T00:00:00Z", "end_dttm": "2026-03-01T00:00:00Z"}
# after
{"layer": 1, "short_descr": "launch-2", "start_dttm": "2026-03-01T00:00:00Z", "end_dttm": "2026-03-02T00:00:00Z"} Defensive patterns
Strategy: validation
Validate before calling
from datetime import datetime
def annotation_valid(layer_id: int, short_descr: str, start: datetime, end: datetime) -> bool:
unique = AnnotationDAO.validate_update_uniqueness(layer_id, short_descr)
dates_ok = not (start and end and end < start)
return unique and dates_ok Try / catch
try:
CreateAnnotationCommand(properties).run()
except AnnotationInvalidError as ex:
field_errors = {e.field_name: e.messages for e in ex._exceptions}
return {"errors": field_errors}, 422 Prevention
- Always send start_dttm/end_dttm in one timezone (UTC) and assert ordering before submit.
- Check short_descr uniqueness on the target layer via the annotation filter API before create.
- Make seed scripts idempotent so re-runs never duplicate descriptions.
When it happens
Trigger: POST /api/v1/annotation/ with a short_descr that already exists on the target layer; or with end_dttm < start_dttm (e.g. timezone mix-up flipping the order); both problems at once produce two nested exceptions.
Common situations: Duplicate 'launch'/'deploy' markers on the same layer; ISO strings with and without timezone offsets parsed into datetimes whose comparison surprises the author; replaying an import script twice creating the second copy.
Related errors
- Annotation parameters are invalid.
- Annotation layer not found.
- Annotation layer parameters are invalid.
- Annotation layer parameters are invalid.
- Database parameters are invalid.
AI-assisted analysis of apache/superset@f4587218dd (2026-08-14).
Data as JSON: /api/errors/609916d2a06c6887.
Report an issue: GitHub.