langchain-ai/langchain · error · ValueError

Both `{var_name}_path` and `{var_name}` cannot be provided.

Error message

Both `{var_name}_path` and `{var_name}` cannot be provided.

What it means

In `_load_template`, a prompt config may specify a template either inline (`template: ...`) or by file (`template_path: ...`), but not both. Supplying both `{var_name}` and `{var_name}_path` (e.g. `template` and `template_path`, or `prefix` and `prefix_path`) raises this `ValueError` because the loader would not know which source wins.

Source

Thrown at libs/core/langchain_core/prompts/loading.py:95

    if config_type not in type_to_loader_dict:
        msg = f"Loading {config_type} prompt not supported"
        raise ValueError(msg)

    prompt_loader = type_to_loader_dict[config_type]
    return prompt_loader(config, allow_dangerous_paths=allow_dangerous_paths)


def _load_template(
    var_name: str, config: dict[str, Any], *, allow_dangerous_paths: bool = False
) -> dict[str, Any]:
    """Load template from the path if applicable."""
    # Check if template_path exists in config.
    if f"{var_name}_path" in config:
        # If it does, make sure template variable doesn't also exist.
        if var_name in config:
            msg = f"Both `{var_name}_path` and `{var_name}` cannot be provided."
            raise ValueError(msg)
        # Pop the template path from the config.
        template_path = Path(config.pop(f"{var_name}_path"))
        if not allow_dangerous_paths:
            _validate_path(template_path)
        # Resolve symlinks before checking the suffix so that a symlink named
        # "exploit.txt" pointing to a non-.txt file is caught.
        resolved_path = template_path.resolve()
        # Load the template.
        if resolved_path.suffix == ".txt":
            template = resolved_path.read_text(encoding="utf-8")
        else:
            msg = (
                f"Unsupported template file format: '{resolved_path.suffix}'. "
                "Only '.txt' files are supported."
            )
            raise ValueError(msg)
        # Set the template variable to the extracted variable.
        config[var_name] = template

View on GitHub (pinned to e32fa9a52e)

Solutions

  1. Delete one of the two keys: keep `template` with the inline text, or keep `template_path` pointing at a `.txt` file.
  2. If you merged configs programmatically, add a pre-check that pops duplicate keys before loading.

Example fix

# before
# prompt.json
# {"_type": "prompt", "template": "Hi {name}", "template_path": "t.txt",
#  "input_variables": ["name"]}
load_prompt('prompt.json')  # ValueError

# after
# {"_type": "prompt", "template": "Hi {name}", "input_variables": ["name"]}
load_prompt('prompt.json')
Defensive patterns

Strategy: validation

Validate before calling

for var in ('template', 'prefix', 'suffix'):
    if var in config and f'{var}_path' in config:
        del config[f'{var}_path']  # inline value wins; or raise
load_prompt_from_config(config)

Type guard

def has_no_inline_path_conflict(config: dict, var: str) -> bool:
    return not (var in config and f'{var}_path' in config)

Prevention

When it happens

Trigger: A JSON/YAML prompt config containing both `"template"` and `"template_path"` keys (or `prefix`+`prefix_path`, `suffix`+`suffix_path` in few-shot configs), passed to `load_prompt`/`load_prompt_from_config`.

Common situations: Editing a config that originally used `template_path` by pasting the template text in but forgetting to delete the path key; merging config files by hand; leftovers from template extraction tooling.

Related errors


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