huggingface/transformers · error · AssertionError

Provided path ({}) should be a directory, not a file

Error message

Provided path ({}) should be a directory, not a file

What it means

AssertionError from GenerationConfig.save_pretrained(): save_directory exists but is a regular file, not a directory. The method must create generation_config.json inside that directory, so a file path (often a mistyped path or an existing JSON file path) is rejected up front.

Source

Thrown at src/transformers/generation/configuration_utils.py:907

                Whether or not to push your model to the Hugging Face model hub after saving it. You can specify the
                repository you want to push to with `repo_id` (will default to the name of `save_directory` in your
                namespace).
            kwargs (`dict[str, Any]`, *optional*):
                Additional key word arguments passed along to the [`~utils.PushToHubMixin.push_to_hub`] method.
        """

        # At save time, validate the instance enforcing strictness -- if any warning/exception would be thrown, we
        # refuse to save the instance.
        # This strictness is enforced to prevent bad configurations from being saved and re-used.
        try:
            self.validate(strict=True)
        except ValueError as exc:
            raise ValueError(str(exc) + "\n\nFix these issues to save the configuration.")

        config_file_name = config_file_name if config_file_name is not None else GENERATION_CONFIG_NAME

        if os.path.isfile(save_directory):
            raise AssertionError(f"Provided path ({save_directory}) should be a directory, not a file")

        os.makedirs(save_directory, exist_ok=True)

        if push_to_hub:
            commit_message = kwargs.pop("commit_message", None)
            repo_id = kwargs.pop("repo_id", str(save_directory).split(os.path.sep)[-1])
            repo_id = hf_api().create_repo(repo_id, exist_ok=True, **kwargs).repo_id
            files_timestamps = self._get_files_timestamps(save_directory)

        output_config_file = os.path.join(save_directory, config_file_name)

        self.to_json_file(output_config_file, use_diff=True, keys_to_pop=["compile_config"])
        logger.info(f"Configuration saved in {output_config_file}")

        if push_to_hub:
            self._upload_modified_files(
                save_directory,
                repo_id,

View on GitHub (pinned to a597f97485)

Solutions

  1. Pass a directory path: cfg.save_pretrained('./my_config_dir') — the file generation_config.json is created inside it
  2. If a stray file occupies the name, rename or remove it: os.remove('bad_path') then retry
  3. Check first: assert not os.path.isfile(save_directory) in your own code before calling

Example fix

# before
cfg.save_pretrained('my_gen_config.json')
# after
cfg.save_pretrained('./output_dir')  # writes ./output_dir/generation_config.json
Defensive patterns

Strategy: validation

Validate before calling

import os
if os.path.exists(save_directory) and not os.path.isdir(save_directory):
    raise ValueError(f'{save_directory} is a file; pass a directory')

Type guard

def is_save_dir(p: str) -> bool:
    import os
    return not os.path.exists(p) or os.path.isdir(p)

Prevention

When it happens

Trigger: cfg.save_pretrained('config.json') or any existing file path; passing a path where a previous run created a file with the intended directory name.

Common situations: User passes the desired output FILE name instead of the directory; a stale file (not directory) left at the target path by an earlier tool.

Related errors


AI-assisted analysis of huggingface/transformers@a597f97485 (2026-08-14). Data as JSON: /api/errors/e9ab7f8ba3b45ad8. Report an issue: GitHub.