mikebridge opened a new issue, #42568:
URL: https://github.com/apache/superset/issues/42568

   ### 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`:**
   
   - #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:
   
   ```bash
   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:
   
   ```toml
   [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:
   
   ```bash
   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
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to