{"record":{"id":"8e9c349c167a41e7","repo":"apache/superset","slug":"dashboard-parameters-are-invalid-8e9c34","errorCode":null,"errorMessage":"Dashboard parameters are invalid.","messagePattern":"Dashboard parameters are invalid\\.","errorType":"validation","errorClass":"DashboardInvalidError","httpStatus":422,"severity":"error","filePath":"superset/commands/dashboard/create.py","lineNumber":76,"sourceCode":"        return dashboard\n\n    def validate(self) -> None:\n        exceptions: list[ValidationError] = []\n        # An absent slug must stay ``None`` (not default to ``\"\"``):\n        # ``validate_slug_uniqueness`` deliberately checks empty strings, so\n        # coercing absent → \"\" would run the check as ``slug == \"\"`` and 422\n        # every slugless create once any empty-string-slug row exists. This\n        # mirrors the update path, which also passes ``None`` through.\n        slug: str | None = self._properties.get(\"slug\")\n\n        # Validate slug uniqueness\n        if not DashboardDAO.validate_slug_uniqueness(slug):\n            exceptions.append(DashboardSlugExistsValidationError())\n\n        populate_subjects(self._properties, exceptions)\n\n        if exceptions:\n            raise DashboardInvalidError(exceptions=exceptions)\n","sourceCodeStart":58,"sourceCodeEnd":77,"githubUrl":"https://github.com/apache/superset/blob/f4587218dd19d046c3e4d00063e7d27f8a2ed354/superset/commands/dashboard/create.py#L58-L77","documentation":"DashboardInvalidError from CreateDashboardCommand.validate() aggregates validation failures: a slug that already exists on another dashboard (DashboardSlugExistsValidationError) or invalid owners/roles produced by populate_subjects. The exception carries the list of per-field errors in its 'exceptions' attribute, which the API serializes into a 422 response.","triggerScenarios":"POST /api/v1/dashboard/ with a 'slug' matching an existing dashboard's slug; or with owners/roles entries (ids or usernames) that fail the subject-population checks (unknown user, no permission to assign that owner).","commonSituations":"Scripts creating dashboards with fixed slugs that collide after re-running; migrating dashboards between environments where the slug is already taken; passing an owner id from a different environment's user table.","solutions":["Inspect the 422 response body: each item in exceptions names the exact failing field (slug vs owners/roles).","If the slug is taken, choose a different slug or omit it and let Superset generate one; or delete/rename the conflicting dashboard first.","For owner failures, verify the owner ids/usernames exist in this environment and that the caller may assign them.","Use DashboardDAO.validate_slug_uniqueness(slug) before creating."],"exampleFix":"# before\nCreateDashboardCommand({'dashboard_title': 'Ops', 'slug': 'ops'}).run()  # 'ops' taken\n\n# after\nfrom superset.daos.dashboard import DashboardDAO\nslug = 'ops'\nif not DashboardDAO.validate_slug_uniqueness(slug):\n    slug = f'ops-{uuid4().hex[:6]}'\nCreateDashboardCommand({'dashboard_title': 'Ops', 'slug': slug}).run()","handlingStrategy":"validation","validationCode":"from superset.daos.dashboard import DashboardDAO\n\nslug = props.get('slug')\nif slug and not DashboardDAO.validate_slug_uniqueness(slug):\n    props['slug'] = f\"{slug}-{uuid4().hex[:6]}\"  # or surface a 409 to the user","typeGuard":null,"tryCatchPattern":"try:\n    CreateDashboardCommand(props).run()\nexcept DashboardInvalidError as ex:\n    for sub in ex.exceptions:\n        # each sub names the field: slug / owners / roles\n        field_errors[sub.field_name] = str(sub)","preventionTips":["Generate slugs from titles plus a random suffix in automation.","Validate owner/role ids exist in the target environment before create.","Parse the exceptions list in the 422 body instead of guessing the field."],"tags":["dashboard","create","validation","slug","unique-constraint"],"backgroundTag":null,"analyzedSha":"f4587218dd19d046c3e4d00063e7d27f8a2ed354","analyzedAt":"2026-08-14T22:39:27.425Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}