Vendored Dependency Version Skew#
The LanceDB Python wheel (lancedb._lancedb.abi3.so) is a compiled Rust extension built with maturin. Because Rust crates are statically linked at compile time, the lance-format crates baked into a released wheel can lag behind both the current workspace and the installed pylance Python package. This version mismatch is the primary source of split-brain bugs where the same logical operation produces different results depending on which code path runs it.
How the Wheel Gets Its Lance Version#
The workspace Cargo.toml pins every lance crate (e.g. lance-core, lance-encoding, lance-io, etc.) to a single exact version via a git tag from the upstream lance-format/lance repository. At the time of this writing the workspace pins =10.1.0-beta.1. The python/Cargo.toml consumes those pins via lance-core.workspace = true and similar directives — so whichever tag is in the workspace at build time is what gets compiled into the wheel.
Once distributed, the wheel's Rust code cannot be updated by pip. Installing a newer pylance Python package does not change the native extension; the two halves can silently diverge.
Concrete Impact: Table.optimize() Data Corruption#
A diagnosed incident shows the real-world consequence. lancedb 0.36.0b0 was released while the workspace still pinned lance 9.0.0. Inspection of the distributed binary confirmed this:
$ strings -a .venv/lib/python3.12/site-packages/lancedb/_lancedb.abi3.so \
| grep -oE 'lance-(core|table|encoding|io|file|index|datafusion)-[0-9]+\.[0-9]+\.[0-9]+' | sort -u
lance-core-9.0.0
lance-datafusion-9.0.0
...
Meanwhile the installed pylance package reported 10.0.0-beta.6 — a version that includes a fix for blob-column corruption (lance-format/lance#7955). The divergence produced different outcomes on the same data :
| API | Code path | lance version used | Result |
|---|---|---|---|
Table.optimize() | In-process Rust extension | 9.0.0 (pre-fix) | CORRUPT |
Table.compact_files() | Delegates to pylance | 10.0.0b6 (post-fix) | MATCH |
Storage versions 2.0 and 2.2 were both affected; 2.1 was not .
Why CI Cannot Catch This#
The tests extra in python/pyproject.toml pins pylance==9.0.0rc1, which matched the vendored crate at the time. CI therefore runs both halves in lockstep and cannot observe any divergence. Any lance bug fixed after the vendor pin is silently absent from wheel-based code paths while appearing fixed via compact_files() (which calls out to the installed pylance). There is no lockfile-level mechanism that can detect this skew because lancedb lists pylance only as an optional extra, not a required dependency.
Automation for Keeping Versions in Sync#
LanceDB uses a GitHub Actions workflow (.github/workflows/codex-update-lance-dependency.yml) to automatically open PRs when a new lance release is available. The workflow calls ci/check_lance_release.py and uses an AI agent (Codex) to update the workspace pin and regenerate Cargo.lock.
For stable releases, ci/validate_stable_lance.py scans both Cargo.toml and python/pyproject.toml and hard-fails if any beta tag is found — preventing stable wheels from being cut while a preview lance is vendored.
Key Takeaways for Engineers#
- To find the vendored lance version in a deployed wheel, run
strings -a <path-to-_lancedb.abi3.so> | grep -oE 'lance-core-[0-9]+\.[0-9]+\.[0-9]+'. - Any
Tablemethod that dispatches into the Rust extension (optimize,create_index, etc.) uses the vendored version; methods that callself.to_lance()delegate to the installedpylance. - When debugging behavioral differences between
Table.*andLanceDataset.*on identical data, check whether the vendored crate pre-dates a relevant upstream fix. - The durable fix is to keep the vendored crate version and the
pylancefloor inpyproject.tomlin lockstep, and to run CI against the pylance version users will actually install — not the one matching the vendored crate .
Relevant Files#
| File | Purpose |
|---|---|
Cargo.toml | Workspace-level lance version pins |
python/Cargo.toml | Python extension's dependency declarations |
python/pyproject.toml | pylance optional/test deps |
.github/workflows/codex-update-lance-dependency.yml | Automated lance version update workflow |
ci/validate_stable_lance.py | Blocks stable release with beta lance |