{"record":{"id":"56beaaee22fe2739","repo":"apache/superset","slug":"annotation-layer-not-found-56beaa","errorCode":null,"errorMessage":"Annotation layer not found.","messagePattern":"Annotation layer not found\\.","errorType":"exception","errorClass":"AnnotationLayerNotFoundError","httpStatus":400,"severity":"error","filePath":"superset/commands/annotation_layer/update.py","lineNumber":56,"sourceCode":"class UpdateAnnotationLayerCommand(BaseCommand):\n    def __init__(self, model_id: int, data: dict[str, Any]):\n        self._model_id = model_id\n        self._properties = data.copy()\n        self._model: Optional[AnnotationLayer] = None\n\n    @transaction(on_error=partial(on_error, reraise=AnnotationLayerUpdateFailedError))\n    def run(self) -> Model:\n        self.validate()\n        assert self._model\n        return AnnotationLayerDAO.update(self._model, self._properties)\n\n    def validate(self) -> None:\n        exceptions: list[ValidationError] = []\n        name = self._properties.get(\"name\", \"\")\n        self._model = AnnotationLayerDAO.find_by_id(self._model_id)\n\n        if not self._model:\n            raise AnnotationLayerNotFoundError()\n\n        if not AnnotationLayerDAO.validate_update_uniqueness(\n            name, layer_id=self._model_id\n        ):\n            exceptions.append(AnnotationLayerNameUniquenessValidationError())\n\n        if exceptions:\n            raise AnnotationLayerInvalidError(exceptions=exceptions)\n","sourceCodeStart":38,"sourceCodeEnd":65,"githubUrl":"https://github.com/apache/superset/blob/f4587218dd19d046c3e4d00063e7d27f8a2ed354/superset/commands/annotation_layer/update.py#L38-L65","documentation":"AnnotationLayerNotFoundError from AnnotationLayerUpdateCommand.validate() (update.py:56): AnnotationLayerDAO.find_by_id(self._model_id) returned None — the layer being PATCHed does not exist. HTTP 404. Distinct from the 422 invalid error raised later in the same method for name uniqueness.","triggerScenarios":"PATCH /api/v1/annotation_layer/<id> where the layer was deleted in another session; renaming from a stale list view; scripted updates against wrong environment ids.","commonSituations":"Concurrent layer management by multiple admins; long-lived settings pages; drift between staging and prod metadata databases.","solutions":["GET /api/v1/annotation_layer/<id> to confirm existence before PATCH.","If 404, refresh the layer list and reapply the change to a live layer.","Guard automation with an existence check and skip/log on missing rows."],"exampleFix":"# before\nUpdateAnnotationLayerCommand(model_id=12, {\"name\": \"New\"}).run()\n\n# after\nfrom superset.daos.annotation_layer import AnnotationLayerDAO\nif AnnotationLayerDAO.find_by_id(12) is None:\n    log.warning(\"layer 12 missing; refresh and retry\")\nelse:\n    UpdateAnnotationLayerCommand(model_id=12, {\"name\": \"New\"}).run()","handlingStrategy":"validation","validationCode":"from superset.daos.annotation_layer import AnnotationLayerDAO\n\nif AnnotationLayerDAO.find_by_id(layer_id) is None:\n    return {\"error\": f\"layer {layer_id} not found\"}, 404","typeGuard":null,"tryCatchPattern":"try:\n    UpdateAnnotationLayerCommand(model_id, properties).run()\nexcept AnnotationLayerNotFoundError:\n    refresh_layers(); return {\"error\": \"layer deleted elsewhere\"}, 404","preventionTips":["GET the layer before PATCH; 404 means refresh the list, don't retry blindly.","In automation, guard updates by existence and log skips.","Resolve layers by name in cross-environment scripts."],"tags":["annotation-layer","not-found","update"],"backgroundTag":null,"analyzedSha":"f4587218dd19d046c3e4d00063e7d27f8a2ed354","analyzedAt":"2026-08-14T22:39:27.425Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}