Skip to content

Improvements to UX when getting 404 errors from Hugging Face#2519

Open
miabbott wants to merge 6 commits intocontainers:mainfrom
miabbott:improve-hf-404-error
Open

Improvements to UX when getting 404 errors from Hugging Face#2519
miabbott wants to merge 6 commits intocontainers:mainfrom
miabbott:improve-hf-404-error

Conversation

@miabbott
Copy link
Copy Markdown
Contributor

@miabbott miabbott commented Mar 15, 2026

I tried running some models from HF using ramalama and was encountering errors about the HF CLI not being installed. I knew this was incorrect, so I fed the debug output from my attempts to OpenCode + Sonnet 4.6 to diagnose the error and suggest changes.

It found that when HF returned 404 errors, the errors were not properly caught and raised the generic message about the missing CLI.

This PR improves the error handling when a 404 response is received from HF and will report back to the user any valid GGUF files that can be fetched for the repository.

Previous to this PR:

$ ramalama run huggingface://Qwen/Qwen2.5-7B-Instruct-GGUF/qwen2.5-7b-instruct-q4_k_m.gguf                                                                           
Downloading hf://Qwen/Qwen2.5-7B-Instruct-GGUF/qwen2.5-7b-instruct-q4_k_m.gguf ...                                                                             
Trying to pull hf://Qwen/Qwen2.5-7B-Instruct-GGUF/qwen2.5-7b-instruct-q4_k_m.gguf ...                                                                          
Error: huggingface cli download not available

After this PR:

$ ramalama run huggingface://Qwen/Qwen2.5-7B-Instruct-GGUF/qwen2.5-7b-instruct-q4_k_m.gguf
Downloading hf://Qwen/Qwen2.5-7B-Instruct-GGUF/qwen2.5-7b-instruct-q4_k_m.gguf ...                                                                             
Trying to pull hf://Qwen/Qwen2.5-7B-Instruct-GGUF/qwen2.5-7b-instruct-q4_k_m.gguf ...                                                                          
Error: qwen2.5-7b-instruct-q4_k_m.gguf' not found in 'Qwen/Qwen2.5-7B-Instruct-GGUF'.                                                                          

Available GGUF files in this repository:                                       
  qwen2.5-7b-instruct-fp16-00001-of-00004.gguf                                 
  qwen2.5-7b-instruct-fp16-00002-of-00004.gguf                                 
  qwen2.5-7b-instruct-fp16-00003-of-00004.gguf                                 
  qwen2.5-7b-instruct-fp16-00004-of-00004.gguf                                 
  qwen2.5-7b-instruct-q2_k.gguf                                                
  qwen2.5-7b-instruct-q3_k_m.gguf                                              
  qwen2.5-7b-instruct-q4_0-00001-of-00002.gguf                                 
  qwen2.5-7b-instruct-q4_0-00002-of-00002.gguf                                 
  qwen2.5-7b-instruct-q4_k_m-00001-of-00002.gguf                                                                                                               
  qwen2.5-7b-instruct-q4_k_m-00002-of-00002.gguf                                                                                                               
  qwen2.5-7b-instruct-q5_0-00001-of-00002.gguf                                 
  qwen2.5-7b-instruct-q5_0-00002-of-00002.gguf                                 
  qwen2.5-7b-instruct-q5_k_m-00001-of-00002.gguf                                                                                                               
  qwen2.5-7b-instruct-q5_k_m-00002-of-00002.gguf                                                                                                               
  qwen2.5-7b-instruct-q6_k-00001-of-00002.gguf                                 
  qwen2.5-7b-instruct-q6_k-00002-of-00002.gguf                                 
  qwen2.5-7b-instruct-q8_0-00001-of-00003.gguf                                 
  qwen2.5-7b-instruct-q8_0-00002-of-00003.gguf                                 
  qwen2.5-7b-instruct-q8_0-00003-of-00003.gguf                            

Summary by Sourcery

Improve Hugging Face transport error handling for missing GGUF files to provide clearer feedback and avoid misleading CLI fallback errors.

Bug Fixes:

  • Raise FileNotFoundError on HTTP 404 responses from the Hugging Face checksum API so missing files are correctly identified.
  • Ensure pull() re-raises FileNotFoundError immediately so the unused CLI fallback path is not triggered for non-existent models.

Enhancements:

  • Add a helper to list GGUF files in a Hugging Face repository and surface them in error messages when a requested file is missing.
  • Clarify the NotImplementedError message for Hugging Face CLI download arguments to explain that CLI fallback is not supported for GGUF downloads.

Tests:

  • Add comprehensive unit tests covering 404 handling, GGUF file listing, improved metadata error messages, pull() behavior, and the updated CLI fallback error message.

Previously all HTTP errors from the checksum API were caught and
re-raised as a generic KeyError, losing the signal that the file
simply does not exist on the server. Split the 404 case out into
a FileNotFoundError carrying the URL, so callers can distinguish
"file not found" from other transient or auth failures.

Assisted-by: OpenCode 1.2.26 (Claude Sonnet 4.6)
Signed-off-by: Micah Abbott <[email protected]>
Introduces a thin wrapper around the existing fetch_repo_files
function that filters results to .gguf files only. This will be
used to generate actionable suggestions when a user specifies a
filename that does not exist in the repository.

Assisted-by: OpenCode 1.2.26 (Claude Sonnet 4.6)
Signed-off-by: Micah Abbott <[email protected]>
When HuggingfaceRepositoryModel.fetch_metadata encounters a
FileNotFoundError (HTTP 404) for the requested file, fetch the
list of GGUF files actually present in the repository and include
them in the error message, so the user knows what to use instead.

Assisted-by: OpenCode 1.2.26 (Claude Sonnet 4.6)
Signed-off-by: Micah Abbott <[email protected]>
The CLI fallback path in pull() is only meaningful when the HTTP
download fails due to a transient or auth error. A FileNotFoundError
means the file does not exist at all; falling through to the CLI
would never succeed and previously produced a completely misleading
"huggingface cli download not available" error. Re-raise immediately
with the original exception instead.

Assisted-by: OpenCode 1.2.26 (Claude Sonnet 4.6)
Signed-off-by: Micah Abbott <[email protected]>
The previous NotImplementedError said "huggingface cli download not
available", implying the hf tool was missing. This method is a
deliberate dead-end because the hf CLI does not support direct GGUF
file downloads; update the message to reflect that accurately.

Assisted-by: OpenCode 1.2.26 (Claude Sonnet 4.6)
Signed-off-by: Micah Abbott <[email protected]>
Add test_huggingface_404_ux.py covering the five commits that improve
the user experience when a 404 is returned by the HuggingFace registry:

- fetch_checksum_from_api_base: verify 404 raises FileNotFoundError
  (not KeyError) and that the URL is included in the exception, while
  other HTTP errors and URLErrors still raise KeyError
- fetch_gguf_files: verify it returns a sorted, filtered list of .gguf
  paths, returns an empty list on exceptions, and forwards the revision
  argument to fetch_repo_files
- HuggingfaceRepositoryModel.fetch_metadata: verify the error message
  lists available GGUF files when present, falls back to a browse URL
  when none are found, and always re-raises FileNotFoundError
- pull(): verify FileNotFoundError propagates immediately without
  invoking the CLI fallback, while other exceptions still attempt it
- get_cli_download_args: verify NotImplementedError is raised with the
  updated message and that the old misleading text is absent

Assisted-by: OpenCode 1.2.26 (Claude Sonnet 4.6)
Signed-off-by: Micah Abbott <[email protected]>
@sourcery-ai
Copy link
Copy Markdown
Contributor

sourcery-ai Bot commented Mar 15, 2026

Reviewer's Guide

Improves Hugging Face GGUF download UX by turning 404 checksum lookups into explicit FileNotFoundError, surfacing available GGUF files for the repo, preventing a misleading CLI fallback path, clarifying the CLI error message, and adding unit tests around the new behavior.

File-Level Changes

Change Details Files
Treat HTTP 404s from the Hugging Face checksum API as FileNotFoundError instead of generic KeyError, so missing files can be handled explicitly.
  • Update fetch_checksum_from_api_base to special‑case urllib.error.HTTPError with status 404 and raise FileNotFoundError including the URL.
  • Preserve KeyError behavior for non‑404 HTTPError, JSON decode failures, and URLError, but with clearer error messages.
ramalama/hf_style_repo_base.py
When a requested GGUF file is missing, list available GGUF files in the repository (or a browse URL) instead of falling back to a misleading HF CLI error.
  • Add fetch_gguf_files helper that calls fetch_repo_files and returns a sorted list of .gguf paths, swallowing any exceptions and returning an empty list on failure.
  • Wrap HuggingfaceRepositoryModel.fetch_metadata checksum lookup in a try/except for FileNotFoundError; on 404, compute a detailed FileNotFoundError message including the requested file, repository name, and either a bulleted list of available GGUF files from fetch_gguf_files or a Hugging Face browse URL when none are found.
  • Ensure successful fetch_metadata still sets blob_url, model_hash, and model_filename as before.
ramalama/transports/huggingface.py
Ensure pull() does not trigger the CLI fallback path for missing files, and clarify that CLI downloads are not supported for GGUF files.
  • In HF-style repo pull(), add an except FileNotFoundError clause that re‑raises immediately so that missing files do not fall through to the CLI download path and produce a confusing error.
  • Update Huggingface.get_cli_download_args to keep it intentionally unimplemented but with a clarified NotImplementedError message stating that CLI fallback is not supported for Hugging Face GGUF file downloads and that callers should not reach this code path.
ramalama/hf_style_repo_base.py
ramalama/transports/huggingface.py
Add comprehensive unit tests to cover 404 handling, GGUF listing, metadata error messages, pull() behavior, and the updated CLI error message.
  • Introduce test_huggingface_404_ux.py to cover: 404 vs non‑404 behavior of fetch_checksum_from_api_base; behavior of fetch_gguf_files under normal, empty, and error conditions; HuggingfaceRepositoryModel.fetch_metadata behavior for missing files with/without available GGUF files and for successful checksum fetches; pull() propagation of FileNotFoundError vs other exceptions with respect to CLI fallback; and the new get_cli_download_args NotImplementedError message.
  • Use helpers to construct HTTPError and mocked urlopen responses, and extensive patching of Hugging Face transport functions to isolate behavior.
test/unit/test_huggingface_404_ux.py

Possibly linked issues


Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@gemini-code-assist
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the user experience when encountering 404 errors from Hugging Face repositories. Previously, such errors would lead to a generic "huggingface cli download not available" message. The changes now provide specific feedback, indicating if a requested GGUF file is not found and listing other available GGUF files within the repository, or suggesting a browse URL if no GGUF files are present. This prevents misleading error messages and guides users more effectively.

Highlights

  • Improved 404 Error Handling: HTTP 404 responses from Hugging Face API calls now correctly raise a FileNotFoundError instead of a generic KeyError, allowing for more specific error management.
  • GGUF File Listing: A new utility function was introduced to fetch and list all available GGUF files within a specified Hugging Face repository.
  • Informative Error Messages: When a requested GGUF file is not found, the error message now includes a list of available GGUF files in the repository or a direct link to browse the repository.
  • CLI Fallback Prevention: The system now explicitly re-raises FileNotFoundError before attempting a misleading CLI fallback for missing files.
  • Clarified CLI Error Message: The NotImplementedError message for CLI downloads has been updated to explain why CLI fallback is not supported for GGUF files and that the file might not exist.
  • Comprehensive Unit Tests: New unit tests were added to cover all aspects of the improved 404 error handling and user experience.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • ramalama/hf_style_repo_base.py
    • Imported urllib.error for specific exception handling.
    • Modified fetch_checksum_from_api_base to differentiate between HTTP 404 errors (raising FileNotFoundError) and other HTTP/URL errors (raising KeyError).
    • Added an exception block in the pull method to catch and re-raise FileNotFoundError, preventing further processing.
  • ramalama/transports/huggingface.py
    • Introduced fetch_gguf_files to retrieve and sort .gguf file paths from a Hugging Face repository, handling potential exceptions by returning an empty list.
    • Updated HuggingfaceRepositoryModel.fetch_metadata to catch FileNotFoundError during checksum fetching, then use fetch_gguf_files to construct a user-friendly error message listing available GGUF files or providing a repository URL.
    • Revised the get_cli_download_args method's NotImplementedError message to clarify that CLI fallback is not supported for GGUF downloads and that the file might not exist.
  • test/unit/test_huggingface_404_ux.py
    • Added a new test file to validate the enhanced 404 error handling, fetch_gguf_files functionality, fetch_metadata behavior, pull method's exception propagation, and the updated get_cli_download_args error message.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Copy Markdown
Contributor

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've left some high level feedback:

  • In fetch_gguf_files you catch a bare Exception and silently return an empty list; consider narrowing this to a more specific set of network/HTTP errors or at least logging/debugging the failure so that genuine programmer errors (e.g., bad response shape) don’t get masked as “no files found.”
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In `fetch_gguf_files` you catch a bare `Exception` and silently return an empty list; consider narrowing this to a more specific set of network/HTTP errors or at least logging/debugging the failure so that genuine programmer errors (e.g., bad response shape) don’t get masked as “no files found.”

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request significantly improves the user experience when encountering 404 errors from Hugging Face by providing a much clearer error message, including a list of available files. The changes are well-implemented, with specific error handling for 404s and logic to prevent misleading fallback errors. The addition of comprehensive unit tests ensures the new functionality is robust. I have one suggestion to improve the robustness of the new helper function.

Comment on lines +141 to +142
except Exception:
return []
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Catching a broad Exception and silently returning can hide underlying issues, such as an AttributeError if the API returns an unexpected format for a file path. This makes debugging more difficult.

It would be more robust to log the exception to aid in debugging. Since this function is for enhancing an error message, swallowing the error is acceptable, but logging it is highly recommended.

For example:

    except Exception as e:
        logger.debug(f"Could not fetch GGUF file list for '{repo_name}': {e}")
        return []

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like a reasonable concern.

# The file does not exist on the server; the CLI fallback cannot
# help here, and falling through would produce a misleading error.
raise
except Exception as e:
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The fix for the 404 handling is to just remove this block, it existed as a fallback to handle pulling safetensors models until it was implemented. Since #2224 it should be ok to remove it, but we would need to test a number of scenarios first to be sure it's safe to do.

self.model_hash = f"sha256:{fetch_checksum_from_api(self.organization, self.name)}"
try:
self.model_hash = f"sha256:{fetch_checksum_from_api(self.organization, self.name)}"
except FileNotFoundError:
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Users would typically specific the Hugging Face model in <org>/<name>:<quant> format e.g hf://bartowski/gemma-2-9b-it-GGUF:Q4_K_M.

If the organisation name or the repo name are incorrect then will get a 404 here.

It looks like the intention here is to then list the available ggufs, but that doesn't make sense - either the org or the repo name is incorrect so it wouldn't be possible to list the available ggufs (could list the available repos for the org if there is an API for this but that would be huge in some cases, thousands for bartowski!).

I think it would be better to just raise an issue for all this to discuss. It is not a good first issue for a new contributor.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the feedback! We can discuss in #2524

@github-actions
Copy link
Copy Markdown

A friendly reminder that this PR had no activity for 30 days.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants