langchain-ai/langchain · error · ValueError

{save_path} must be json or yaml

Error message

{save_path} must be json or yaml

What it means

save() only supports JSON and YAML destinations. After resolving the path, if the suffix is neither .json nor .yaml/.yml, it raises ValueError('<path> must be json or yaml'). The extension is the format selector, so unrecognized or missing extensions are rejected before any file is written (note the parent directory is created first).

Source

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

            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)


def _get_document_info(
    doc: Document, prompt: BasePromptTemplate[str]
) -> dict[str, Any]:
    base_info = {"page_content": doc.page_content, **doc.metadata}
    missing_metadata = set(prompt.input_variables).difference(base_info)
    if len(missing_metadata) > 0:
        required_metadata = [
            iv for iv in prompt.input_variables if iv != "page_content"
        ]
        msg = (
            f"Document prompt requires documents to have metadata variables: "
            f"{required_metadata}. Received document with missing metadata: "
            f"{list(missing_metadata)}."
        )
        raise ValueError(
            create_message(message=msg, error_code=ErrorCode.INVALID_PROMPT_INPUT)

View on GitHub (pinned to e32fa9a52e)

Solutions

  1. Rename the destination to end in .json, .yaml, or .yml
  2. If you need another format, save to .json first and convert with your own tooling

Example fix

# before
prompt.save("prompts/instructions.txt")  # ValueError

# after
prompt.save("prompts/instructions.yaml")
Defensive patterns

Strategy: validation

Validate before calling

from pathlib import Path

def valid_save_path(p: str) -> bool:
    return Path(p).suffix in {".json", ".yaml", ".yml"}

Prevention

When it happens

Trigger: Calling prompt.save('prompt.txt'), prompt.save('prompts/prompt') with no extension, or passing a path whose casing/format token is not exactly .json/.yaml/.yml.

Common situations: Exporting prompts into existing artifact pipelines that expect .txt/.md/.toml; typos like '.yamal'; or dynamically built filenames that drop the extension.

Related errors


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