huggingface/transformers · error · AssertionError

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

Error message

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

What it means

AssertionError from PretrainedConfig.save_pretrained when the given save_directory path is an existing file. The method must create config.json inside a directory, so passing a file path (including a path ending in config.json) is rejected before any write happens.

Source

Thrown at src/transformers/configuration_utils.py:570

        self.rope_parameters = value

    def save_pretrained(self, save_directory: str | os.PathLike, push_to_hub: bool = False, **kwargs):
        """
        Save a configuration object to the directory `save_directory`, so that it can be re-loaded using the
        [`~PreTrainedConfig.from_pretrained`] class method.

        Args:
            save_directory (`str` or `os.PathLike`):
                Directory where the configuration JSON file will be saved (will be created if it does not exist).
            push_to_hub (`bool`, *optional*, defaults to `False`):
                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.
        """
        if os.path.isfile(save_directory):
            raise AssertionError(f"Provided path ({save_directory}) should be a directory, not a file")

        generation_parameters = self._get_generation_parameters()
        if len(generation_parameters) > 0:
            raise ValueError(
                "Some generation parameters are set in the model config. These should go into `model.generation_config`"
                f"as opposed to `model.config`. \nGeneration parameters found: {str(generation_parameters)}",
            )

        os.makedirs(save_directory, exist_ok=True)

        if push_to_hub:
            commit_message = kwargs.pop("commit_message", None)
            repo_id = kwargs.pop("repo_id", 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)

        # This attribute is important to know on load, but should not be serialized on save.
        if "transformers_weights" in self:

View on GitHub (pinned to a597f97485)

Solutions

  1. Pass the directory only: config.save_pretrained('output_dir') — it creates the dir and writes config.json inside
  2. If the path exists as a stale file, remove or rename it, then retry with the directory
  3. Guard with os.path.isdir(...) in shared save helpers

Example fix

# before
config.save_pretrained('out/config.json')
# after
config.save_pretrained('out')
Defensive patterns

Strategy: type-guard

Validate before calling

out = Path(save_path)
if out.is_file():
    out = out.parent
out.mkdir(parents=True, exist_ok=True)
config.save_pretrained(out)

Type guard

def is_save_dir(p: str) -> bool:
    path = Path(p)
    return path.suffix == '' or path.is_dir()  # config.json suffix means a file was passed

Try / catch

try:
    config.save_pretrained(save_path)
except AssertionError as e:
    if 'should be a directory' in str(e):
        config.save_pretrained(Path(save_path).parent)
    else:
        raise

Prevention

When it happens

Trigger: config.save_pretrained('model_dir/config.json') instead of config.save_pretrained('model_dir'); passing an existing file path of any kind; paths computed by joining a filename onto a base path that already exists as a file.

Common situations: Adapting save code from APIs that take full file paths (e.g. json.dump to a file); CLI scripts whose output argument is the config filename; typos where the parent directory was never created and a same-named file exists.

Related errors


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