[uv workspaces] `pulumi install` loses `pulumi-plugin.json` metadata for deps of other `uv` workspace members and is broken with custom `server` plugin
What happened?
The problem
I started using Pulumi Kubernetes Operator and found the following issue: pulumi install attempts to discover Pulumi plugins from the uv.lock file, and it doesn't filter them by the dependency tree of the current Pulumi stack.
In combination with pulumi-plugin.json discovery mechanism for Python packages (searching though the currently installed modules), this may lead to installation errors when any other uv workspace member (Pulumi stack in the monorepo) depends on a package with a custom server, for example the extremely popular pulumi-onepassword:
{
"resource": true,
"name": "onepassword",
"server": "github://api.github.com/1Password/pulumi-onepassword"
}pulumi install never gets the custom server location and fails with an error when attempting to install it from the default server.
Again, the mismatch is:
pulumi installinvokesuv sync --inexactwhich correctly installs dependencies only for the current Pulumi stack (this is correct!)pulumi installthem attempts to install plugins for all Pulumi stacks in theuv.lockfile (uvworkspace members), but not all of them were installed byuv sync(this is wrong!)
References:
- https://github.com/pulumi/pulumi/blob/v3.245.0/sdk/python/toolchain/uv.go#L113-L150
- https://github.com/pulumi/pulumi/blob/v3.245.0/sdk/python/toolchain/uv.go#L338-L365
This issue effectively make every Pulumi stack (e.g. an entire monorepo) in a uv workspace with even one stack depending on pulumi-onepassword broken with Pulumi Operator.
The solution
pulumi install could use:
uv export \
--project "$PROGRAM_DIRECTORY" \
--locked \
--format requirements.txt
--no-header \
--no-annotate \
--no-hashesthis would retrieve the correct subset of this stack's transitive dependencies.
Example
- Project A depends on
pulumi-onepassword. - Project B does not.
- Both share one uv workspace lock.
- Run
pulumi installinside Project B with an empty $PULUMI_HOME. - Pulumi reads
pulumi-onepasswordfrom the global lock, cannot find its metadata in Project B’svenv, guesses[email protected]without its GitHub server, and fails.
Output of pulumi about
CLI
Version 3.221.0
Go Version go1.26.0
Go Compiler gc
Host
OS darwin
Version 26.5.2
Arch arm64
Backend
Name pulumi.com
URL https://app.pulumi.com/danielgafni
User danielgafni
Organizations danielgafni, typesafe
Token type personal
Environment Variables: Name Value PULUMI_IGNORE_AMBIENT_PLUGINS true
Pulumi locates its logs in /var/folders/fq/h88vffdx1wxfm3h6nk44tpc00000gn/T/ by default
Additional context
Looks like this bug was introduced in 3.226.0 by PR #22072
A work-around for me was to pre-download Pulumi plugins and ship then to Pulumi pods ahead of pulumi install.
Contributing
Vote on this issue by adding a reaction. To contribute a fix for this issue, leave a comment (and link to your pull request, if you've opened one already).
Source: pulumi/pulumi