`registry.is_compatible_version` does not split comma-separated `require-dbt-version` (unlike `_parse_versions`), breaking `dbt deps` for every consumer of a package once any version uses that form
- Dominant language
- Rust
- Stars
- 13.8k
- Forks
- 2.6k
- Avg merge
- 21h 31m
- Merged PRs (30d)
- 56
Description
### Is this a new bug in dbt-core?
- [x] I believe this is a new bug in dbt-core
- [x] I have searched the existing issues, and I could not find an existing issue for this bug
### Current Behavior
`dbt deps` fails for any Hub package where **any** published version declares `require-dbt-version` as a single comma-separated string (for example `">=1.10.5,<3.0.0"`), even when the consumer is pinned to a different version of that package.
`dbt/clients/registry.py::is_compatible_version` wraps a bare string in a one-element list and passes each element straight to `VersionSpecifier.from_version_string`, so a comma-separated string is treated as a single (invalid) version and raises `SemverError`. Meanwhile `dbt/config/project.py::_parse_versions` handles the identical field for a project's own `dbt_project.yml`, does `versions.split(",")` first, and its docstring documents the comma form as valid. Two parsers for the same field, one of them rejecting documented syntax.
Because `get_compatible_versions()` calls `is_compatible_version` for every published version before the consumer's version range is applied, one bad version poisons the whole package for every consumer.
Real-world trigger: `the_tuva_project` 1.0.0 metadata on the Hub uses the comma form. Every consumer pinned to an earlier version (we were on `[">=0.17.0","<0.18.0"]`) broke on `dbt deps` the day 1.0.0 was published. Tuva fixed their source (tuva-health/tuva-core#1449) but the Hub still serves the old metadata (dbt-labs/hub.getdbt.com#4695, still open as of 2026-09-11), so consumers are left with two workarounds: `dbt deps --no-version-check`, which skips the compatibility check for every package, or pinning the affected package via `git:` so its metadata never comes from the Hub. We did the latter to keep the check for everything else.
### Expected Behavior
`is_compatible_version` accepts the same three shapes `_parse_versions` accepts (single string, comma-separated string, list). At minimum, an unparseable `require-dbt-version` on one published version should not abort `dbt deps` for the whole package.
### Steps To Reproduce
```python
from dbt.clients import registry
from dbt.config import project
s = ">=1.10.5,<3.0.0"
project._parse_versions(s)
# -> ['>=1.10.5', '<3.0.0'] works
registry.is_compatible_version({"require_dbt_version": [">=1.10.5", "<3.0.0"]}, "1.10.22")
# -> True list form works
registry.is_compatible_version({"require_dbt_version": s}, "1.10.22")
# -> SemverError comma string form fails
```
### Relevant log output
```
Traceback (most recent call last):
File ".../dbt/clients/registry.py", line 140, in is_compatible_version
supported_versions = [
File ".../dbt/clients/registry.py", line 141, in
semver.VersionSpecifier.from_version_string(v) for v in require_dbt_version
File ".../dbt_common/semver.py", line 99, in from_version_string
raise dbt_common.exceptions.base.SemverError(
dbt_common.exceptions.base.SemverError: ">=1.10.5,<3.0.0" is not a valid semantic version.
```
### Environment
- OS: macOS (Darwin 25.3.0, arm64)
- Python: 3.11.15
- dbt-core: 1.10.22 (reproduced above). `registry.py` is byte-identical through 1.12.4 and the failure reproduces there as well.
- dbt-duckdb: 1.10.1
### Which database adapter are you using with dbt?
duckdb (not adapter related, the failure is in package resolution)
### Additional Context
One-line fix: reuse `_parse_versions` (or add a `.split(",")`) inside `is_compatible_version`. Happy to open a PR if that's welcome.
Contributor guide
Assessment
This issue has not been assessed yet.