Skip to content

fix: unblock v0.74.0 crates.io publish, and surface the hf-hub patch/publish gaps - #1093

Closed
michaelneale wants to merge 1 commit into
mainfrom
fix/model-package-publish-repo-id
Closed

fix: unblock v0.74.0 crates.io publish, and surface the hf-hub patch/publish gaps#1093
michaelneale wants to merge 1 commit into
mainfrom
fix/model-package-publish-repo-id

Conversation

@michaelneale

@michaelneale michaelneale commented Jul 27, 2026

Copy link
Copy Markdown
Collaborator

What this fixes

v0.74.0 published its GitHub release and all binaries/GPU bundles fine, but the crates.io publish died 28 of 42 crates in, failing to verify model-package:

error[E0308]: mismatched types
    .repo_id(candidate.target_repo.clone())
             expected `&str`, found `String`
note: method defined here --> hf-hub-1.0.0/src/repository/mod.rs:914:9
error: failed to verify package tarball

That left the workspace half-published: 27 crates at 0.74.0, 15 not.

The code change here is one character (&). The reasons it happened are the actual content of this PR.

Root cause: [patch.crates-io] does not apply to publish-verify

The workspace patches hf-hub to a fork:

[patch.crates-io]
hf-hub = { git = "https://github.com/Mesh-LLM/hf-hub", branch = "mesh-llm" }
  • cargo check / clippy / just build / all normal CI compile against the fork, where .repo_id(String) is accepted → green.
  • cargo publish verifies the packaged tarball outside the workspace, where the patch does not apply. hf-hub resolves from the registry (1.0.0), whose builder takes &str → E0308.

The bug was structurally invisible to every normal build. A borrow compiles under both.

Issue 1 — the preflight gap that let this reach a GA publish

publish_crates_preflight runs scripts/publish-crates.sh --dry-run, which should have caught this. It didn't, because the script intentionally skips verification for any crate whose in-workspace registry deps aren't on crates.io yet:

should_skip_initial_dry_run() {
  ... "dry-run cannot verify ${crate} until ${dep}@${workspace_version} exists in crates.io"
}

model-package lists model-hf and model-ref as unpublished registry deps, so at preflight time (nothing published yet for the new version) its verification was skipped entirely. The failure could therefore only surface during the real publish — after 27 crates had already gone out irreversibly.

So for the whole class of crates with unpublished sibling deps, we currently have no pre-publish type-checking against real registry deps. That's the gap worth fixing, independent of this typo.

Issue 2 — published crates on crates.io do not get the fork

[patch.crates-io] is not transitive. It applies only to builds of this workspace. The published manifest confirms it — model-hf@0.74.0 on crates.io declares:

hf_hub ^1.0.0-rc.1   (package = hf-hub)

i.e. upstream registry hf-hub, not the Mesh-LLM fork. Consequences:

  1. Anyone consuming our crates from crates.io (cargo add model-hf, mesh-llm-host-runtime, mesh-llm-commands, model-package) builds against upstream hf-hub, silently losing what the fork carries.
  2. Those crates must therefore compile against upstream hf-hub — which is only being enforced accidentally, at publish time, as this failure demonstrates.

Is the patch still needed? Yes — verified, and it is not the same feature upstream has

Worth being precise, because upstream does now have byte-range support and it is easy to mistake for resume. Upstream main (hf-hub/src/repository/download.rs) has:

range: Option<std::ops::Range<u64>>,   // caller-specified range reads
//! Range parameters use Rust `std::ops::Range<u64>` semantics

That is a caller-supplied byte-range read on download_file_stream / download_file_to_bytes. It is not resume-after-interruption. Upstream hf-hub/src/cache/storage.rs has no .incomplete / partial-blob handling at all.

The fork's resume commit adds exactly that missing piece:

Resume(u64),
ExistingBlob,
pub(crate) fn incomplete_path(path: &Path) -> PathBuf {
    PathBuf::from(format!("{}.incomplete", path.display()))
}
std::cmp::Ordering::Less if len > 0 => PartialDownloadState::Resume(len),

i.e. .incomplete staging files, partial-length detection, and resume state — restarting an interrupted model download where it left off. Different feature from upstream's range API.

The fork carries 5 commits ahead, all load-bearing for model downloads:

Commit What it does
9d8ba581 Support resumable downloads
e8fb7ac4 Match Python cache fallback on Windows
27573dc6 Don't trust redirect Content-Length as file size
9008c312 Fix import ordering for nightly rustfmt
fd3bfcab Merge of the redirect fix

Touching cache/storage.rs, repository/download.rs, repository/files.rs, xet.rs (~900 added lines). The fork is also 5 commits behind upstream main, and upstream's latest tag is v1.0.0-rc.2 while we depend on ^1.0.0-rc.1 (registry has 1.0.0 final).

So we can't drop the patch — it's carrying real functionality upstream lacks. But the current shape means our crates.io artifacts advertise a dependency we never build or test against. Options to decide between:

  • Upstream the patches to huggingface/hf-hub and drop the fork+patch entirely (cleanest, slowest).
  • Publish the fork under a distinct name (e.g. mesh-llm-hf-hub) and depend on it directly — no [patch] needed, published crates become honest, CI and publish compile the same code.
  • Stop publishing the hf-hub-dependent crates to crates.io if nobody consumes them there.
  • Keep as-is, but add real registry-resolution verification to preflight so breakage can't reach a GA publish.

Not an issue: sibling version pins (correcting an earlier claim)

An earlier revision of this description claimed crates/model-package/Cargo.toml shipped stale 0.72.1 sibling pins. That was wrong — I checked the actual released tag:

$ git show v0.74.0:crates/model-package/Cargo.toml
model-hf  = { path = "../model-hf",  version = "0.74.0" }
model-ref = { path = "../model-ref", version = "0.74.0" }

scripts/release-version.sh has update_versioned_path_dependency_versions() (invoked at lines 244 and 251) which rewrites every { path = ..., version = ... } pin to the release version. The 94 0.72.1 pins visible on main are just un-bumped dev state and are normalized at release time. No action needed.

Validation

  • cargo check -p model-package --bins — pass
  • cargo clippy -p model-package --all-targets -- -D warnings — pass
  • cargo fmt --all --check — pass

Note this fix alone is not sufficient to finish v0.74.0's crates chain: the publish_crates job checks out ref: <tag> (v0.74.0), so the fix must be reachable from the tag it builds. Re-running the old job as-is replays the same failure. Finishing options: resume the chain manually from a checkout containing this fix, or fold it into a v0.74.1.

Rollback

Single revert; the code change is one borrow.

The v0.74.0 crates.io publish failed verifying model-package:

  error[E0308]: mismatched types
    .repo_id(candidate.target_repo.clone())
  note: method defined here (hf-hub-1.0.0) repo_id: &str

The workspace patches hf-hub to a fork via [patch.crates-io], so workspace
builds and CI compile this bin against the fork. cargo publish verifies the
packaged tarball, where the patch does not apply and hf-hub resolves from
crates.io (1.0.0), whose create_repository().repo_id() takes &str. Passing an
owned String only fails on that registry path.

Pass a borrow so both the patched-fork workspace build and the registry
publish-verify build compile.

Assisted-by: Claude Sonnet
@coderabbitai

coderabbitai Bot commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

write_queue_marker now passes candidate.target_repo by reference to the repository builder instead of cloning the string.

Changes

Repository builder update

Layer / File(s) Summary
Borrow target repository identifier
crates/model-package/src/bin/queue-unsloth-layer-packages.rs
write_queue_marker configures repo_id with a borrowed target_repo reference instead of a cloned string.

Estimated code review effort: 1 (Trivial) | ~2 minutes

Suggested reviewers: i386

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title matches the main fix: unblocking the v0.74.0 publish by addressing the hf-hub repo_id mismatch.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/model-package-publish-repo-id

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@michaelneale michaelneale changed the title fix: unblock v0.74.0 crates.io publish (model-package verify against registry hf-hub) fix: unblock v0.74.0 crates.io publish, and surface the hf-hub patch/publish gaps Jul 28, 2026
@michaelneale

Copy link
Copy Markdown
Collaborator Author

@i386 tagging you because the fork here is yours (#709 "Use combined hf-hub fork for model downloads") and two of the three issues below are really design calls rather than review nits.

The code change is one character. The reasons it happened are the point:

  1. [patch.crates-io] doesn't apply to publish-verify. Everything normal (cargo check, clippy, just build, CI) compiles queue-unsloth-layer-packages.rs against your fork, where .repo_id(String) is fine. cargo publish verifies the packaged tarball outside the workspace, where the patch doesn't apply and hf-hub resolves from the registry (1.0.0, repo_id: &str). So this was invisible to every normal build and only blew up mid-GA-publish, after 27 crates had already gone out.

  2. Preflight skipped the crate that broke. publish-crates.sh --dry-run deliberately skips verification for crates whose sibling registry deps aren't published yet — model-package depends on model-hf/model-ref, so it was never verified before the real publish. That means the whole class of crates with unpublished siblings has no pre-publish type-check against real registry deps.

  3. Published crates don't get the fork. This is the one I'd most like your read on. [patch.crates-io] isn't transitive, and model-hf@0.74.0 on crates.io declares hf_hub ^1.0.0-rc.1 — i.e. upstream, not Mesh-LLM/hf-hub. So anyone doing cargo add model-hf builds against upstream hf-hub and silently loses resumable downloads, the Windows cache fallback, and the redirect Content-Length fix. Those 5 fork commits look load-bearing (~900 lines across download.rs/storage.rs/xet.rs), and upstream still hasn't landed resume — so the patch is genuinely needed, but our crates.io artifacts are advertising a dependency we never build or test against.

To answer the obvious question: no, I don't think we can just drop the patch — it's carrying real functionality. But the current shape seems wrong. Options in the PR body; the one I'd lean toward is publishing the fork under its own name (e.g. mesh-llm-hf-hub) so no [patch] is needed and published crates are honest, but you'll know better whether upstreaming is realistic.

Also FYI the fork branch is 5 behind upstream main.

Separately: this fix alone won't finish v0.74.0's crates chain, because publish_crates checks out ref: <tag>, so it needs to be reachable from the tag it builds — either resume the chain manually from a checkout with the fix, or fold it into a v0.74.1. Happy to do either, but didn't want to publish to crates.io by hand without a nod.

@michaelneale

Copy link
Copy Markdown
Collaborator Author

Correcting two things from my comment above, after actually checking rather than assuming.

1. The sibling version pins are NOT broken — I was wrong. I'd flagged model-package shipping stale 0.72.1 pins. That claim was based on reading main, which was lazy. The released tag is correct:

$ git show v0.74.0:crates/model-package/Cargo.toml
model-hf  = { path = "../model-hf",  version = "0.74.0" }
model-ref = { path = "../model-ref", version = "0.74.0" }

scripts/release-version.sh has update_versioned_path_dependency_versions() (called at lines 244/251) that rewrites every { path, version } pin at release time. The 94 0.72.1 pins on main are just un-bumped dev state, normalized on release. Nothing to fix — I've removed that from the PR body.

2. On "does upstream hf-hub have it now?" — my first check was too shallow, but the conclusion holds, for a sharper reason. Upstream main does now have byte-range support, which is easy to mistake for resume:

range: Option<std::ops::Range<u64>>,
//! Range parameters use Rust std::ops::Range<u64> semantics

But that's a caller-supplied range read on download_file_stream/download_file_to_bytes — not resume-after-interruption. Upstream cache/storage.rs has no .incomplete/partial-blob handling at all. The fork adds precisely that:

Resume(u64),
ExistingBlob,
pub(crate) fn incomplete_path(path: &Path) -> PathBuf { ... "{}.incomplete" ... }
std::cmp::Ordering::Less if len > 0 => PartialDownloadState::Resume(len),

So: .incomplete staging, partial-length detection, resume state. Different feature from upstream's range API — so the patch is still genuinely needed. Two things you may still want to weigh in on: the fork is 5 commits behind upstream main, and upstream is now at v1.0.0-rc.2 while we pin ^1.0.0-rc.1 (registry has 1.0.0 final, which is what publish-verify resolved to and where the type mismatch came from).

So it's down to two real issues, both design calls for you: the preflight gap (Issue 1) and published crates not getting the fork (Issue 2).

@michaelneale

Copy link
Copy Markdown
Collaborator Author

Tracking issue for the underlying problems this PR exposes: #1094 (crates.io half-published + hf-hub [patch] gaps). Other v0.74.0 release follow-up: #1088 (container images, @ndizazzo).

@ndizazzo

Copy link
Copy Markdown
Collaborator

Single change captured in #1096 along with Cargo updates and a corrected hf-hub pin - closing in favour of that

@ndizazzo ndizazzo closed this Jul 28, 2026
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.

3 participants