feat(python-setup): recover from a constraint conflict with a Retry-as-DB-Connect fallback - #2186
Merged
Merged
Conversation
…s-DB-Connect fallback *Why* The uv-native "set up Python environment" Full preset pins the cluster/serverless runtime's dependencies, so `uv sync` can fail when those pins conflict with the user's own. The CLI now emits a distinct E_PROVISION_CONFLICT for that case (shipped in CLI v1.16.0). Rather than the generic "adjust your dependencies" message, offer a one-click recovery: re-run as DB Connect (which drops the pins). *What* - E_PROVISION_CONFLICT error code + actionable copy; a genuine pin-vs-local conflict, distinct from the generic E_PROVISION. - Recovery toast (Full preset only): "Retry DB Connect setup" + "Open pyproject.toml"; "Show Logs" dropped from this self-service toast. - Retry restores the CLI's pre-merge pyproject.toml backup (result.backupPath) before re-running with --no-constraints — the pins are merged to disk before provision fails, so --no-constraints alone would leave them in place. Restore is atomic (temp + rename), refuses a backupPath outside the project, and a truthy-backupPath guard falls through to the generic path when absent (e.g. a no-op-merge re-run). - Guarded against loops (dbconnect skips constraints), stale-toast re-provision, and concurrent runs (coalesces onto an in-flight run). - Telemetry: a conflict_retry value on the setup.attempt trigger dimension, paired with the result outcome for the recovery success rate. *Verification* - Unit tests for the conflict copy, run-action dispatch, restore ordering, --no-constraints + adopt, telemetry pairing, no-loop, coalescing, stale/empty/ missing-backupPath fallbacks, and atomic/in-project restore wiring. - Recreated cleanly against main (supersedes #2181, which merged into the preset-picker branch, not main); tsc + targeted unit tests green. Co-authored-by: Isaac <no-reply@databricks.com>
rugpanov
temporarily deployed
to
test-trigger-is
September 9, 2026 16:53 — with
GitHub Actions
Inactive
rugpanov
temporarily deployed
to
test-trigger-is
September 9, 2026 16:53 — with
GitHub Actions
Inactive
Contributor
|
If integration tests don't run automatically, an authorized user can run them manually by following the instructions below: Trigger: Inputs:
Checks will be approved automatically on success. |
rugpanov
temporarily deployed
to
test-trigger-is
September 9, 2026 16:54 — with
GitHub Actions
Inactive
Contributor
Author
|
🤖 Integration tests running for |
misha-db
approved these changes
Sep 10, 2026
Merged
rugpanov
added a commit
that referenced
this pull request
Sep 10, 2026
Release **v2.17.0** of the Databricks VS Code extension. ## What's included - Add a Python environment setup preset picker to choose a Full, DB Connect, or Python-only environment (#2179) - Recover from a dependency constraint conflict during Python setup by offering to retry as a DB Connect environment (#2186) - Add recovery UX for Python download failures (#2164) - Show an actionable error when Python setup hits a merge conflict on a `pyproject.toml` without a `[project]` table (#2180) - Preserve script stdout when an Upload-and-Run file fails (#2171) - Update Databricks CLI to v1.16.0 (#2175, #2183) — see the [CLI release notes](https://github.com/databricks/cli/releases) for changes Changelog curated from the generated output (stripped auto-close refs, dropped internal telemetry/CI-only items). Tracking: DECO-28498. --------- Co-authored-by: releasebot <noreply@github.com> Co-authored-by: @rugpanov <gripanov@gmail.com> Co-authored-by: Isaac <no-reply@databricks.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
The uv-native "set up Python environment" Full preset pins the cluster's
dependencies, so
uv synccan fail when those pins conflict with the user's owndependencies. The CLI now emits a distinct
E_PROVISION_CONFLICTfor thatcase (shipped in CLI v1.16.0, already bundled on
main). Rather than thegeneric
E_PROVISIONtoast ("uv could not resolve the project's dependencies…adjust your dependencies"), offer a one-click recovery: re-run as DB Connect
(
--no-constraints), which drops the conflicting cluster-dependency pins whilekeeping matched Python + databricks-connect.
What
E_PROVISION_CONFLICT— a distinct result-model error code for a genuinepin-vs-local conflict (a generic sync failure stays
E_PROVISION), with itsown copy: "The cluster dependencies conflict with your local dependencies, so
uv sync couldn't resolve the environment."
with Retry DB Connect setup and Open pyproject.toml. "Show Logs" is
dropped from this self-service toast (the channel is still revealed).
merged into
pyproject.toml(diskMutated: true, pre-merge file saved to theCLI's
backupPath). So Retry first restores that backup, then re-runs withthe
dbconnectpreset —--no-constraintsalone would only stop the retryfrom re-adding pins, not remove those already on disk. The restore is atomic
(temp sibling + rename) and refuses a
backupPathresolving outside theproject. When
backupPathis absent/empty (e.g. a no-op-merge re-run), Retryisn't offered and the run falls back to the ordinary doc-link handling.
runGuarded/runResolvedlet the retry re-enter with thedbconnectpreset directly (no re-prompt), coalesced so a click can't race anin-flight run;
dbconnectskips constraints so the retry can't loop; a staletoast's Retry no-ops once the project is ready.
conflict_retryvalue on the existingpython_env.setup.attempttriggerdimension marks recovery runs, paired withthe
python_env.setup.resultoutcome for the recovery success rate. No newevent. A conflict is never report-worthy (it's the user's own dependencies).
Live against the shipped CLI
Unlike when this was first written, CLI v1.16.0 (on
main) emitsE_PROVISION_CONFLICT, so the recovery path is now exercised end-to-end, notdormant. Note: the CLI only populates
backupPathon the first merge; are-run over an already-merged
pyproject.tomlis a no-op merge and returns anempty
backupPath, in which case the run correctly falls through to the genericpath (the truthy-
backupPathguard).Testing
test:unit: new coverage for the conflict copy + fallback doc link, therun-action dispatch,openProjectFile, the controller conflict→retry flow(restore-before-retry ordering,
--no-constraints+ adopt on success,conflict_retrytelemetry paired with its outcome, open pyproject at the run'scwd,
reportOffered: false, missing/empty-backupPathand non-Full fallbacks,restore-failure aborts without a retry attempt), and the atomic/in-project
restore wiring.
tsc+eslint+prettierclean on changed files.Supersedes #2181, which merged into the (now-defunct) preset-picker branch rather
than
main.This pull request and its description were written by Isaac.