BerriAI/litellm · error · ValueError

Prompt template '{prompt_id}' not found

Error message

Prompt template '{prompt_id}' not found

What it means

ValueError from BitBucketPromptManagementClient.get_prompt_template when prompt_manager.get_template(prompt_id) returns None — i.e. the template is not in the loaded prompts dict. This is the typed-guard style of error 348: a deliberate fail-fast because the manager cannot render a template it never loaded. The subsequent render_template call would raise anyway; this check gives a clearer message.

Source

Thrown at litellm/integrations/bitbucket/bitbucket_prompt_manager.py:251

    def get_prompt_template(
        self,
        prompt_id: str,
        prompt_variables: dict[str, Any] | None = None,
    ) -> tuple[str, dict[str, Any]]:
        """
        Get a prompt template and render it with variables.

        Args:
            prompt_id: The ID of the prompt template
            prompt_variables: Variables to substitute in the template

        Returns:
            Tuple of (rendered_prompt, metadata)
        """
        template: Final = self.prompt_manager.get_template(prompt_id)
        if not template:
            raise ValueError(f"Prompt template '{prompt_id}' not found")

        # Render the template
        rendered_prompt: Final = self.prompt_manager.render_template(prompt_id, prompt_variables or {})

        # Extract metadata
        metadata: Final = {
            "model": template.model,
            "temperature": template.temperature,
            "max_tokens": template.max_tokens,
            **template.optional_params,
        }

        return rendered_prompt, metadata

    def pre_call_hook(
        self,
        user_id: str | None,
        messages: list[AllMessageValues],

View on GitHub (pinned to 6c2dcb801b)

Solutions

  1. Use prompt_manager.list_templates() to confirm the id exists before the call
  2. Load on demand: if prompt_id not in prompt_manager.prompts: prompt_manager._load_prompt_from_bitbucket(prompt_id)
  3. Match the id exactly to the .prompt file name (case-sensitive)
  4. Trigger a prompt reload/restart after adding prompt files to the repository

Example fix

# before
rendered, metadata = client.get_prompt_template("summary", {"topic": "x"})

# after
if client.prompt_manager.get_template("summary") is None:
    client.prompt_manager._load_prompt_from_bitbucket("summary")
rendered, metadata = client.get_prompt_template("summary", {"topic": "x"})
Defensive patterns

Strategy: type-guard

Validate before calling

if client.prompt_manager.get_template(prompt_id) is None:
    try:
        client.prompt_manager._load_prompt_from_bitbucket(prompt_id)
    except Exception:
        pass
if client.prompt_manager.get_template(prompt_id) is None:
    raise KeyError(f"Unknown prompt '{prompt_id}'; available: {client.prompt_manager.list_templates()}")

Type guard

def has_prompt_template(client, prompt_id: str) -> bool:
    """Narrow: True only when the template object is loaded."""
    return client.prompt_manager.get_template(prompt_id) is not None

Try / catch

try:
    rendered, metadata = client.get_prompt_template(prompt_id, variables)
except ValueError as e:
    if "not found" in str(e):
        raise KeyError(f"prompt '{prompt_id}' missing; loaded={client.prompt_manager.list_templates()}") from e
    raise

Prevention

When it happens

Trigger: Passing a prompt_id to the LiteLLM prompt-management flow that was never loaded: wrong file name, new prompt file added post-startup, load skipped because initialization only scans certain directories, or id casing mismatch.

Common situations: Using litellm completion with a BitBucket-backed prompt id that does not correspond to a .prompt file; deploying a new prompt without restarting/reloading the proxy.

Related errors


AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15). Data as JSON: /api/errors/2458037e9ea3f008. Report an issue: GitHub.