Skip to content

Emit E_PROVISION_CONFLICT for uv sync resolution conflicts - #6479

Open
rugpanov wants to merge 3 commits into
setup-local/orthogonal-flagsfrom
setup-local/provision-conflict
Open

Emit E_PROVISION_CONFLICT for uv sync resolution conflicts#6479
rugpanov wants to merge 3 commits into
setup-local/orthogonal-flagsfrom
setup-local/provision-conflict

Conversation

@rugpanov

@rugpanov rugpanov commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Why

databricks environments setup-local wrapped every uv sync failure as
E_PROVISION. The VPEX extension's recovery flow needs to distinguish a
dependency version conflict — the project's dependencies can't be satisfied
against the pins this command wrote — from a generic sync failure it can't fix by
relaxing constraints (a build-backend error, a permissions problem, a transport
error, or an unavailable package). Constraints are already written at the point of
failure (merge precedes provision, so error.diskMutated=true), which the recovery
flow relies on. Fixes DECO-28365.

What

  • New error code E_PROVISION_CONFLICT (libs/localenv/result.go), emitted
    from the provision phase.
  • Classification is gated on the CLI's own conflict detection, not on uv's
    output. The merge phase already detects a provable version conflict between the
    user's dependencies and the environment pins and records it as the
    W_USER_CONSTRAINT_CONFLICT warning (libs/localenv/warnings.go, PEP 440
    interval math on provably-disjoint ranges). When a uv sync failure coincides
    with that warning, the failure is that conflict surfacing, so it is reported as
    E_PROVISION_CONFLICT (libs/localenv/pipeline.go, hasConstraintConflictWarning).
    Every other sync failure keeps E_PROVISION.
  • This is deliberately precise, not broad: an unavailable package or a
    requires-python mismatch (neither is a W_USER_CONSTRAINT_CONFLICT) stays
    E_PROVISION, so a consumer never gets a conflict code for a failure that
    relaxing constraints can't fix. It also needs no stderr string-matching.
  • The failing phase (provision), diskMutated=true, and the E_CANCELED
    reclassification are unchanged. PostProvision (pip seed) and EnsurePython
    keep their existing codes.
  • Telemetry: adds SetupLocalErrorCodeProvisionConflict and the mapping case
    (cmd/environments/telemetry.go, libs/telemetry/protos/setup_local.go), kept
    exhaustive by the linter and TestErrorCodeCoversLocalenv. A matching value in
    the universe lumberjack proto should follow (ingestion ignores unknown values,
    so the two PRs can land in either order).

Testing

  • Unit (libs/localenv/pipeline_test.go): a uv sync failure with a
    merge W_USER_CONSTRAINT_CONFLICTE_PROVISION_CONFLICT
    (failurePhase=provision, diskMutated=true); a uv sync failure without
    it — even one whose stderr looks like a resolver error → E_PROVISION. Both
    cross-platform.
  • Acceptance (acceptance/localenv/provision-conflict/): a real setup-local
    run where the user pins pip==24.0 and the remote constraints pin pip<24, so
    the merge flags the conflict; a fake uv on PATH (the psql acceptance
    precedent — a real uv sync conflict needs a specific managed Python installed
    offline, which CI can't guarantee) fails uv sync. The golden asserts
    error.code=E_PROVISION_CONFLICT, failurePhase=provision, diskMutated=true,
    and the W_USER_CONSTRAINT_CONFLICT warning. Windows-disabled like the psql
    tests; the unit tests cover the logic cross-platform.
  • gofmt, go vet, golangci-lint (root module), and go build ./... clean.

Stacked on #6464. Review/merge that first; this PR's base will retarget to
main once #6464 lands.

This pull request and its description were written by Isaac.

rugpanov and others added 3 commits September 2, 2026 10:14
`databricks environments setup-local` wrapped every `uv sync` failure as
E_PROVISION. The extension's recovery flow needs to tell a dependency-resolution
failure — the remote pins just written can't be satisfied against the user's
local dependencies — apart from a generic sync failure it can't fix by adjusting
constraints.

Classify a `uv sync` failure as the new E_PROVISION_CONFLICT when uv's stderr
carries its resolver banner ("No solution found when resolving dependencies");
every other sync failure keeps E_PROVISION. The failing phase (provision),
diskMutated=true, and the E_CANCELED reclassification are unchanged. Adds the
matching telemetry enum value and an acceptance golden that drives a real
setup-local run against a fake uv failing sync with the resolver banner.

Co-authored-by: Isaac <no-reply@databricks.com>
Three independent reviewers converged: matching uv's "No solution found" stderr
classified every resolution failure — including an unavailable package, which
relaxing constraints can't fix — as a conflict, broader than the ticket's "remote
pins conflict with the user's dependencies" and misleading to consumers.

Gate the code on the CLI's own detection instead: emit E_PROVISION_CONFLICT when
a uv sync failure coincides with the merge phase's W_USER_CONSTRAINT_CONFLICT
warning (a provable disjoint-version conflict), else keep E_PROVISION. Removes the
stderr string-matching (and its brittleness / the errors-string-matching concern)
entirely. Adds pipeline unit tests for the conflict and generic-failure paths;
the acceptance golden and telemetry mapping are unchanged in outcome.

Co-authored-by: Isaac <no-reply@databricks.com>
Make explicit in provision() that E_PROVISION_CONFLICT gating on the merge's
W_USER_CONSTRAINT_CONFLICT signal can coincide with an unrelated sync failure —
and that this is intentional: the warning proves a real conflict exists, so
relaxing the pins is a necessary step regardless, and uv stays the source of
truth for whether sync fails while the CLI's own detection classifies why. No
behavior change. Raised in review (Codex/Claude), kept as-is per decision.

Co-authored-by: Isaac <no-reply@databricks.com>
@rugpanov
rugpanov marked this pull request as ready for review September 2, 2026 08:36
@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Approval status: pending

/acceptance/localenv/ - needs approval

6 files changed
Suggested: @anton-107
Also eligible: @rclarey, @misha-db

/cmd/environments/ - needs approval

Files: cmd/environments/telemetry.go, cmd/environments/telemetry_test.go
Suggested: @anton-107
Also eligible: @rclarey, @misha-db

/libs/localenv/ - needs approval

Files: libs/localenv/pipeline.go, libs/localenv/pipeline_test.go, libs/localenv/result.go
Suggested: @anton-107
Also eligible: @rclarey, @misha-db

/libs/telemetry/ - needs approval

Files: libs/telemetry/protos/setup_local.go
Suggested: @renaudhartert-db
Also eligible: @simonfaltum, @hectorcast-db, @parthban-db, @tanmay-db, @Divyansh-db, @tejaskochar-db, @mihaimitrea-db, @chrisst, @rauchy

General files (require maintainer)

Files: .nextchanges/cli/setup-local-provision-conflict.md
Based on git history:

  • @janniklasrose -- recent work in .nextchanges/cli/

Any maintainer (@andrewnester, @anton-107, @denik, @pietern, @shreyas-goenka, @simonfaltum, @renaudhartert-db, @janniklasrose, @lennartkats-db, @rclarey) can approve all areas.
See OWNERS for ownership rules.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant