apache/superset · error · CommandInvalidError

; ".join(str(message) for message in ex.messages)

Error message

; ".join(str(message) for message in ex.messages)

What it means

When a v1 dataset import assigns a dataset a non-default catalog while the target database has multi-catalog support disabled, the underlying MultiCatalogDisabledValidationError is re-raised as CommandInvalidError so the REST layer returns 422 (validation error) instead of a generic 500. The message is the joined validation messages from the original exception.

Source

Thrown at superset/commands/dataset/importers/v1/__init__.py:80

        # import related databases
        database_ids: dict[str, int] = {}
        for file_name, config in configs.items():
            if file_name.startswith("databases/") and config["uuid"] in database_uuids:
                database = import_database(config, overwrite=False)
                database_ids[str(database.uuid)] = database.id

        # import datasets with the correct parent ref
        for file_name, config in configs.items():
            if (
                file_name.startswith("datasets/")
                and config["database_uuid"] in database_ids
            ):
                config["database_id"] = database_ids[config["database_uuid"]]
                try:
                    import_dataset(config, overwrite=overwrite)
                except MultiCatalogDisabledValidationError as ex:
                    # surface as a 422 validation error instead of a generic 500
                    raise CommandInvalidError(
                        "; ".join(str(message) for message in ex.messages),
                        [ex],
                    ) from ex

View on GitHub (pinned to f4587218dd)

Solutions

  1. Remove or set the 'catalog' field to the target database's default catalog in the uploaded YAML
  2. Enable multi-catalog on the target connection if the engine supports it (update the SQLAlchemy URI / engine settings so allow_multi_catalog is true)
  3. Import into a database connection whose default catalog matches the dataset's catalog

Example fix

# before (exported YAML)
catalog: hive
# after (match target default catalog)
catalog: default
# or omit the key entirely
Defensive patterns

Strategy: try-catch

Validate before calling

from superset.commands.dataset.importers.v1.utils import validate_catalog

for cfg in dataset_configs:  # before import, pre-flight each dataset config
    if cfg.get('catalog'):
        db = session.query(Database).filter_by(id=cfg['database_id']).first()
        if db and (default := db.get_default_catalog()) is not None:\
           not db.allow_multi_catalog and cfg['catalog'] != default:
            cfg['catalog'] = default  # normalize to the target default
# then run the import

Try / catch

from superset.commands.exceptions import CommandInvalidError
try:
    client.post('/api/v1/dataset/import/', files=...)
except CommandInvalidError as ex:
    # 422-class error; ex.messages lists per-config issues — fix YAML and retry once
    ...

Prevention

When it happens

Trigger: POST/PUT to /api/v1/dataset/import (or dashboard import that includes datasets) with a bundle where a dataset's config has a 'catalog' value different from the database's default catalog, and the database's engine spec has allow_multi_catalog disabled (or the engine does not support catalogs at all with a set default).

Common situations: Exporting a dataset from a multi-catalog engine (e.g. Trino, Spark with catalogs) and importing it into a deployment where the connection string pins a single catalog; feature flag or engine-spec differences between source and target instances.

Related errors


AI-assisted analysis of apache/superset@f4587218dd (2026-08-14). Data as JSON: /api/errors/614eed0f949facc5. Report an issue: GitHub.