{"record":{"id":"00c3b23dd76fcc40","repo":"apache/superset","slug":"annotation-layer-parameters-are-invalid","errorCode":null,"errorMessage":"Annotation layer parameters are invalid.","messagePattern":"Annotation layer parameters are invalid\\.","errorType":"validation","errorClass":"AnnotationLayerInvalidError","httpStatus":422,"severity":"error","filePath":"superset/commands/annotation_layer/create.py","lineNumber":54,"sourceCode":"class CreateAnnotationLayerCommand(BaseCommand):\n    def __init__(self, data: dict[str, Any]):\n        self._properties = data.copy()\n\n    @transaction(on_error=partial(on_error, reraise=AnnotationLayerCreateFailedError))\n    def run(self) -> Model:\n        self.validate()\n        return AnnotationLayerDAO.create(attributes=self._properties)\n\n    def validate(self) -> None:\n        exceptions: list[ValidationError] = []\n\n        name = self._properties.get(\"name\", \"\")\n\n        if not AnnotationLayerDAO.validate_update_uniqueness(name):\n            exceptions.append(AnnotationLayerNameUniquenessValidationError())\n\n        if exceptions:\n            raise AnnotationLayerInvalidError(exceptions=exceptions)\n","sourceCodeStart":36,"sourceCodeEnd":55,"githubUrl":"https://github.com/apache/superset/blob/f4587218dd19d046c3e4d00063e7d27f8a2ed354/superset/commands/annotation_layer/create.py#L36-L55","documentation":"AnnotationLayerInvalidError (CommandInvalidError, 422) from AnnotationLayerCreateCommand.validate(): the only check is name uniqueness via AnnotationLayerDAO.validate_update_uniqueness(name). If the name is already used by another annotation layer, AnnotationLayerNameUniquenessValidationError ('Name must be unique', field 'name') is collected and this error raised carrying it.","triggerScenarios":"POST /api/v1/annotation_layer/ with a name that already exists (uniqueness is case-insensitive per DAO implementation); double-submit of the create form; re-running a seed script without cleanup.","commonSituations":"Seeding default layers twice; two admins creating similarly named layers; retry of a timed-out create that actually succeeded server-side.","solutions":["Check GET /api/v1/annotation_layer/?q=(name:eq:<name>) and reuse the existing layer instead of creating.","Make seed scripts idempotent: upsert by name (fetch, then update or create).","Disable the submit button while the create request is pending to avoid duplicates."],"exampleFix":"# before\nCreateAnnotationLayerCommand({\"name\": \"Deploys\"}).run()  # runs twice -> 422\n\n# after\nfrom superset.daos.annotation_layer import AnnotationLayerDAO\nif not AnnotationLayerDAO.validate_update_uniqueness(\"Deploys\"):\n    layer = AnnotationLayerDAO.find_by_name(\"Deploys\")  # reuse\nelse:\n    CreateAnnotationLayerCommand({\"name\": \"Deploys\"}).run()","handlingStrategy":"validation","validationCode":"from superset.daos.annotation_layer import AnnotationLayerDAO\n\nif not AnnotationLayerDAO.validate_update_uniqueness(name):\n    return {\"error\": f\"layer name '{name}' already exists\"}, 422","typeGuard":null,"tryCatchPattern":"try:\n    CreateAnnotationLayerCommand({\"name\": name}).run()\nexcept AnnotationLayerInvalidError as ex:\n    if any(\"unique\" in str(m) for e in ex._exceptions for m in e.messages):\n        return reuse_existing_layer_by_name(name)","preventionTips":["Make layer-creation scripts idempotent: fetch-by-name, update-or-create instead of blind create.","Pre-check name uniqueness via the annotation_layer filter API.","Prevent duplicate form submissions in the UI."],"tags":["annotation-layer","validation","uniqueness","create"],"backgroundTag":null,"analyzedSha":"f4587218dd19d046c3e4d00063e7d27f8a2ed354","analyzedAt":"2026-08-14T22:39:27.425Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}