Skip to content

Fix offline simulation with huggingface_hub 1.27 - #8414

Open
hanouticelina wants to merge 2 commits into
mainfrom
fix-offline-simulation-hfh-1.27
Open

Fix offline simulation with huggingface_hub 1.27#8414
hanouticelina wants to merge 2 commits into
mainfrom
fix-offline-simulation-hfh-1.27

Conversation

@hanouticelina

Copy link
Copy Markdown
Contributor

Summary

Surfaced by the huggingface_hub v1.27.0.rc0 RC test branch, where 6 tests in tests/test_load.py fail: ci-test-huggingface-hub-1.27.0.rc0-release.

They're all offline-simulation tests, and the failures are a test-harness issue rather than a regression in huggingface_hub:

  • test_offline_dataset_module_factory'datasets.packaged_modules.text.text' != 'datasets.packaged_modules.cache.cache'
  • test_offline_dataset_module_factory_with_capital_letters_in_name → same, with csv.csv
  • test_load_dataset_from_hub / test_load_dataset_namespaceDatasetNotFoundError instead of the expected ConnectionError
  • test_load_dataset_cached_from_hub[True/False]'Using the latest cached version of the dataset' never logged

Root cause

offline() patches the module global huggingface_hub.utils._http._GLOBAL_CLIENT with a mock raising httpx.ConnectError.

Since huggingface/huggingface_hub#4614, _http_backoff_base fetches the client on every attempt instead of once before the retry loop (a closed httpx.Client can't be reused). close_session() is called on httpx.ConnectError and sets _GLOBAL_CLIENT = None, so:

  1. attempt 1 hits the mock → ConnectErrorclose_session() wipes the patched global
  2. attempt 2 calls get_session(), sees None, and rebuilds a real client via _GLOBAL_CLIENT_FACTORY
  3. the request goes to the network for real, and offline simulation is silently defeated

Which is exactly what the CI logs show — one Retrying in 1s [Retry 1/5] line, then the test proceeding as if online.

Minimal reproducer, patching _GLOBAL_CLIENT with a raising mock and calling http_backoff("HEAD", ...):

huggingface_hub 1.26.1 -> mock called 3x, ConnectError propagates
huggingface_hub 1.27   -> mock called 1x, request succeeds (real 404)

Fix

Patch _GLOBAL_CLIENT_FACTORY alongside _GLOBAL_CLIENT, so a client rebuilt mid-retry is the mock as well. _GLOBAL_CLIENT_FACTORY has existed since huggingface_hub v1.0, so it's safe under the existing IS_HF_HUB_1_x branch. The <1.0 branch is unchanged.

Testing

Against huggingface_hub main (1.27.0.dev0):

# before
FAILED tests/test_load.py::LoadTest::test_offline_dataset_module_factory
FAILED tests/test_load.py::LoadTest::test_offline_dataset_module_factory_with_capital_letters_in_name
2 failed, 109 deselected in 7.17s

# after
9 passed, 102 deselected in 285.43s (0:04:45)

(the 6 failing tests plus 3 parametrized siblings)

And against huggingface_hub==1.26.1, to confirm no backward-compat break:

tests/test_offline_util.py + tests/test_load.py -k "test_offline_util or test_offline_dataset_module_factory"
5 passed, 109 deselected in 94.53s

Draft for now — opening it so the fix is ready when you bump to 1.27.

Patch the client factory as well, so a client rebuilt mid-retry is also the mock.
@HuggingFaceDocBuilderDev

Copy link
Copy Markdown

The docs for this PR live here. All of your documentation changes will be reflected on that endpoint. The docs are available until 30 days after the last update.

@hanouticelina
hanouticelina marked this pull request as ready for review August 7, 2026 12:56
@hanouticelina

Copy link
Copy Markdown
Contributor Author

✅ looks good to me

@hanouticelina
hanouticelina requested a review from lhoestq August 7, 2026 12:56
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.

2 participants