{"record":{"id":"a4edca31d2742fff","repo":"apache/superset","slug":"dashboard-parameters-are-invalid","errorCode":null,"errorMessage":"Dashboard parameters are invalid.","messagePattern":"Dashboard parameters are invalid\\.","errorType":"validation","errorClass":"DashboardInvalidError","httpStatus":422,"severity":"error","filePath":"superset/commands/dashboard/copy.py","lineNumber":62,"sourceCode":"        # session. The change-record listener stamps\n        # ``version_transaction.action_kind = 'clone'`` so the new\n        # dashboard's baseline records read as \"Cloned from <source>\"\n        # in the timeline instead of \"Dashboard created\".\n        # Method-scoped imports — defer the versioning bootstrap path\n        # (``Model.metadata`` and Continuum-adjacent setup) out of this\n        # command's module-load graph; see ``changes.py`` module\n        # docstring for the broader init-order rationale.\n        from superset import db\n        from superset.versioning.changes import ACTION_KIND_CLONE, ACTION_KIND_KEY\n\n        db.session.info[ACTION_KIND_KEY] = ACTION_KIND_CLONE\n        return DashboardDAO.copy_dashboard(self._original_dash, self._properties)\n\n    def validate(self) -> None:\n        if not self._properties.get(\"dashboard_title\") or not self._properties.get(\n            \"json_metadata\"\n        ):\n            raise DashboardInvalidError()\n        if not security_manager.is_editor(self._original_dash):\n            raise DashboardForbiddenError()\n","sourceCodeStart":44,"sourceCodeEnd":65,"githubUrl":"https://github.com/apache/superset/blob/f4587218dd19d046c3e4d00063e7d27f8a2ed354/superset/commands/dashboard/copy.py#L44-L65","documentation":"DashboardInvalidError is raised by CopyDashboardCommand.validate() when the copy properties dict lacks a truthy 'dashboard_title' or lacks 'json_metadata'. Both are mandatory inputs for creating a clone, since the copy is created via DashboardDAO.copy_dashboard with those properties.","triggerScenarios":"Calling the dashboard copy endpoint (POST /api/v1/dashboard/<id>/copy or the SupersetClient dashboard copy) with a payload missing dashboard_title or json_metadata, or with dashboard_title set to an empty string.","commonSituations":"Custom scripts building the copy payload manually and forgetting json_metadata; frontend code that copies a dashboard whose source json_metadata was null; API clients modeled on outdated payload schemas.","solutions":["Include both 'dashboard_title' (non-empty) and 'json_metadata' in the copy request payload.","If copying programmatically, seed the payload from the source dashboard: {'dashboard_title': src.dashboard_title + ' (copy)', 'json_metadata': src.json_metadata or '{}'}).","Validate the payload against the copy request schema before sending."],"exampleFix":"# before\nprops = {'dashboard_title': 'Sales copy'}  # json_metadata missing\nCopyDashboardCommand(dash, props).run()\n\n# after\nprops = {\n    'dashboard_title': 'Sales copy',\n    'json_metadata': dash.json_metadata or '{}',\n}\nCopyDashboardCommand(dash, props).run()","handlingStrategy":"validation","validationCode":"props = {\n    'dashboard_title': src.dashboard_title + ' (copy)' or 'Copied dashboard',\n    'json_metadata': src.json_metadata or '{}',\n}\nassert props['dashboard_title'] and props['json_metadata']","typeGuard":null,"tryCatchPattern":"try:\n    CopyDashboardCommand(src, props).run()\nexcept DashboardInvalidError as ex:\n    # inspect ex.exceptions for the per-field reason\n    report_validation(ex.exceptions)","preventionTips":["Always seed copy payloads from the source dashboard's own fields.","Default json_metadata to '{}' when the source has none.","Add a payload schema check in API clients before the request."],"tags":["dashboard","copy","validation","payload"],"backgroundTag":null,"analyzedSha":"f4587218dd19d046c3e4d00063e7d27f8a2ed354","analyzedAt":"2026-08-14T22:39:27.425Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}