langchain-ai/langchain · error · NotImplementedError

Prompt {self} does not support saving.

Error message

Prompt {self} does not support saving.

What it means

save() raises NotImplementedError when the prompt's serialized dict (from _dict_for_compat) lacks the '_type' key. '_type' identifies the prompt class for deserialization; a custom or third-party prompt type that does not implement the legacy dict()/_type convention cannot be round-tripped through save/load.

Source

Thrown at libs/core/langchain_core/prompts/base.py:412

            ValueError: If the prompt has partial variables.
            ValueError: If the file path is not json or yaml.
            NotImplementedError: If the prompt type is not implemented.

        Example:
            ```python
            prompt.save(file_path="path/prompt.yaml")
            ```
        """
        if self.partial_variables:
            msg = "Cannot save prompt with partial variables."
            raise ValueError(msg)

        # Fetch dictionary to save. Preserve deprecated `dict()` overrides until
        # `dict()` is removed.
        prompt_dict = self._dict_for_compat()
        if "_type" not in prompt_dict:
            msg = f"Prompt {self} does not support saving."
            raise NotImplementedError(msg)

        # Convert file to Path object.
        save_path = Path(file_path)

        directory_path = save_path.parent
        directory_path.mkdir(parents=True, exist_ok=True)

        resolved_path = save_path.resolve()
        if resolved_path.suffix == ".json":
            with resolved_path.open("w", encoding="utf-8") as f:
                json.dump(prompt_dict, f, indent=4)
        elif resolved_path.suffix.endswith((".yaml", ".yml")):
            with resolved_path.open("w", encoding="utf-8") as f:
                yaml.dump(prompt_dict, f, default_flow_style=False)
        else:
            msg = f"{save_path} must be json or yaml"
            raise ValueError(msg)

View on GitHub (pinned to e32fa9a52e)

Solutions

  1. Use one of the built-in serializable types (PromptTemplate, ChatPromptTemplate) for anything you need to save
  2. For custom prompts, implement your own serialization (pickle-free, e.g. Pydantic model_dump) instead of save()
  3. Add a '_type' entry to the dict your custom class produces, mirroring built-ins, if you also implement a matching loader

Example fix

# before
class MyPrompt(BasePromptTemplate):
    ...
MyPrompt(...).save("p.yaml")  # NotImplementedError

# after
# serialize via Pydantic instead
data = my_prompt.model_dump()
Path("p.json").write_text(json.dumps(data, default=str))
Defensive patterns

Strategy: fallback

Validate before calling

def is_serializable_prompt(prompt) -> bool:
    return "_type" in prompt._dict_for_compat()

Try / catch

try:
    prompt.save(path)
except NotImplementedError:
    # custom prompt: fall back to your own serialization
    path.write_text(prompt.model_dump_json())

Prevention

When it happens

Trigger: Calling .save() on a custom subclass of BasePromptTemplate (or StringPromptTemplate) that overrides formatting without exposing a '_type' in its dict representation.

Common situations: Users with bespoke prompt classes (e.g. custom FewShotPrompt variants or framework-provided templates outside core) attempting the documented prompt.save(file_path=...) flow.

Related errors


AI-assisted analysis of langchain-ai/langchain@e32fa9a52e (2026-08-14). Data as JSON: /api/errors/0d3bc14fbfe6752b. Report an issue: GitHub.