dbt-labs/dbt-core · error · anyhow
{filename}'s Requires-Dist disagrees with the sdist: sdist d
Error message
{filename}'s Requires-Dist disagrees with the sdist: sdist deps={:?}, wheel deps={:?} What it means
The wheel's METADATA Requires-Dist set must exactly equal the dependencies declared in the sdist's pyproject. This bail fires when the sets differ (added, removed, or differently-specified dependencies), catching wheels built from a different dependency set than the sdist.
Source
Thrown at crates/dbt-ci/src/sdist.rs:165
let expected_python = spec.requires_python.as_deref();
let actual_python = metadata.requires_python.as_deref();
if actual_python != expected_python {
bail!(
"{filename} declares Requires-Python {actual:?} but the sdist says \
{expected:?}; point `--pyproject-dir` at the pyproject that built \
these wheels",
actual = actual_python.unwrap_or("(absent)"),
expected = expected_python.unwrap_or("(absent)"),
);
}
let expected_deps: std::collections::BTreeSet<&str> =
spec.dependencies.iter().map(|d| d.trim()).collect();
let actual_deps: std::collections::BTreeSet<&str> =
metadata.requires_dist.iter().map(|d| d.trim()).collect();
if expected_deps != actual_deps {
bail!(
"{filename}'s Requires-Dist disagrees with the sdist: sdist deps={:?}, \
wheel deps={:?}",
expected_deps,
actual_deps,
);
}
Ok(())
}
/// The `*.dist-info/METADATA` bytes from a wheel held in memory.
fn wheel_metadata(wheel: &[u8]) -> Result<Option<Vec<u8>>> {
let mut archive = zip::ZipArchive::new(Cursor::new(wheel)).context("open wheel as zip")?;
let name = archive
.file_names()
.find(|n| {
n.ends_with("/METADATA")
&& n.split('/')
.next()View on GitHub (pinned to 0267ce9170)
Solutions
- Rebuild the wheels from the same pyproject as the sdist so Requires-Dist matches exactly.
- Point --pyproject-dir at the pyproject that actually built these wheels.
- Diff the two dep lists printed in the error and reconcile pyproject.toml (add missing deps or update version specifiers), then rebuild.
Example fix
# before
sdist deps: {"click>=8", "pydantic>=2"}
wheel deps: {"click>=8"}
# after
add pydantic>=2 to the wheel build (rebuild wheels from current pyproject.toml) Defensive patterns
Strategy: validation
Validate before calling
# compare wheel deps vs pyproject deps before the release step
python -c "import tomllib,sys; print(sorted(tomllib.load(open('pyproject.toml','rb'))['project']['dependencies']))"
unzip -p wheel/*.whl '*/METADATA' | grep '^Requires-Dist:' | sort Try / catch
if let Err(e) = check_wheel_metadata_agrees(...) {
if e.to_string().contains("Requires-Dist") {
eprintln!("dependency drift between sdist and wheels; rebuild wheels: {e:#}");
}
return Err(e);
} Prevention
- Rebuild wheels after any dependency change in pyproject.toml.
- Never mix wheels from different commits/versions in one release.
- Point --pyproject-dir at the exact project the wheels were built from.
- Diff sdist vs wheel metadata in CI before publishing.
When it happens
Trigger: check_wheel_metadata_agrees normalizes both dependency lists into trimmed BTreeSets and bails when they are not equal — e.g. wheel built before a new dependency was added to pyproject, or wheel extras/markers formatted differently after trimming.
Common situations: Adding/removing a dependency and reusing stale wheels; --pyproject-dir pointing at an older/newer copy of the project; dependency strings differing only in whitespace is tolerated, but different version specifiers or markers are not.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- {filename} declares Requires-Python {actual:?} but the sdist
- no prebuilt {name} {ver} wheel for this platform; available
- {filename} has no *.dist-info/METADATA
- unsupported target triple {:?}
- this backend does not build sdists; use `dbt-ci pypi pack --
AI-assisted analysis of dbt-labs/dbt-core@0267ce9170 (2026-09-07).
Data as JSON: /api/errors/22290c00609c619a.
Report an issue: GitHub.