Skip to content

superset-extensions bundle fails: CLI's unbounded apache-superset-core resolves to stale PyPI 0.1.0 #42568

Description

@mikebridge

Bug description

superset-extensions bundle fails for any extension when the CLI is installed from a source checkout with pip, producing no .supx artifact:

File ".../superset_extensions_cli/cli.py", line 172, in build_manifest
    return Manifest(
pydantic_core._pydantic_core.ValidationError: 1 validation error for Manifest
id
  Field required [type=missing, input_value={'publisher': '...', ...}]

Root cause — a version skew between the CLI and apache-superset-core:

  • feat(extensions): add a Storage API for extensions #39171 changed Manifest.id from a required input field to a @computed_field on BaseExtension, and correctly updated build_manifest() to stop passing id.
  • superset-extensions-cli/pyproject.toml declares its dependency as bare apache-superset-core, with the comment "no bounds for apache-superset-core until we have a stable version".
  • PyPI still serves apache-superset-core 0.1.0, published 2026-05-11 — two months before that change — where id is still a required input field.

So a pip install ./superset-extensions-cli gets new CLI code against stale core, and build_manifest() omits a field that the installed core still requires.

How to reproduce

From a clean apache/superset checkout at master:

python3 -m venv /tmp/v
/tmp/v/bin/pip install ./superset-extensions-cli
/tmp/v/bin/python -c "from superset_core.extensions.types import Manifest; print('id' in Manifest.model_fields)"

Prints True — pip resolved 0.1.0 from PyPI, where id is a required input field. At master it is computed, so this prints False. Running superset-extensions bundle in that venv then fails as above.

On the [tool.uv.sources] workaround

pyproject.toml already redirects both packages to local editable paths:

[tool.uv.sources]
apache-superset-core = { path = "./superset-core", editable = true }
apache-superset-extensions-cli = { path = "./superset-extensions-cli", editable = true }

That is the right mechanism, but it does not appear to apply to uv pip. On uv 0.9.21, from clean venvs, all three of these still resolved apache-superset-core 0.1.0 from PyPI rather than linking ./superset-core:

cwd command result
repo root uv pip install -e ./superset-extensions-cli PyPI 0.1.0
repo root uv pip install ./superset-extensions-cli PyPI 0.1.0
outside repo uv pip install <path>/superset-extensions-cli PyPI 0.1.0

In the editable case, core landed in site-packages rather than as a link to ./superset-core. This matches uv's documented split — tool.uv.sources is honoured by the project interface (uv sync, uv run, uv add), not by the pip-compatible uv pip interface. uv sync from the repo root very likely does work; if a uv pip install -e appeared to work, it may have been in a venv that had already been synced.

Additional context

Two cases the workspace redirect cannot cover, which is why a bound or a release probably matters:

  1. Consumers outside this repo. We build extensions in a separate repository that vendors Superset as a submodule and installs the CLI from ./superset-oss/superset-extensions-cli. A tool.uv.sources entry in Superset's root pyproject.toml never applies to an install driven from another project, regardless of pip vs uv.
  2. Anyone installing the published CLI from PyPI, who gets the same stale core with no checkout to redirect to.

We have worked around it downstream by installing superset-core and the CLI from the submodule together, which is version-manager-agnostic:

pip install ./superset-oss/superset-core ./superset-oss/superset-extensions-cli

Possible fixes upstream, in rough order of durability:

  • Publish an apache-superset-core release matching current master, so the unbounded dependency resolves to something compatible.
  • Add a lower bound (apache-superset-core>=<next>) at release-cut time, so a stale core fails resolution rather than failing at runtime with a schema error.
  • Optionally, have build_manifest() fail with a clearer message when the installed core's Manifest disagrees with what the CLI passes — the current pydantic error gives no hint that two packages are out of step.

Happy to send a PR for whichever shape you prefer.

Superset version

master / latest-dev

Python version

3.11

Node version

I don't know

Browser

Not applicable

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    Status
    To Do

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions