{"record":{"id":"7b3daf50191d672f","repo":"BerriAI/litellm","slug":"prompt-prompt-id-version-str-not-found-in-pro","errorCode":null,"errorMessage":"Prompt '{prompt_id}'{version_str} not found in prompt directory","messagePattern":"Prompt '(.+?)'(.+?) not found in prompt directory","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"litellm/integrations/dotprompt/dotprompt_manager.py","lineNumber":131,"sourceCode":"        \"\"\"\n        Compile a .prompt file into a PromptManagementClient structure.\n\n        This method:\n        1. Loads the prompt template from the .prompt file (with optional version)\n        2. Renders it with the provided variables\n        3. Converts the rendered text into chat messages\n        4. Extracts model and optional parameters from metadata\n        \"\"\"\n\n        if prompt_id is None:\n            raise ValueError(\"prompt_id is required for dotprompt manager\")\n\n        try:\n            # Get the prompt template (versioned or base)\n            template: Final = self.prompt_manager.get_prompt(prompt_id=prompt_id, version=prompt_version)\n            if template is None:\n                version_str: Final = f\" (version {prompt_version})\" if prompt_version else \"\"\n                raise ValueError(f\"Prompt '{prompt_id}'{version_str} not found in prompt directory\")\n\n            # Render the template with variables (pass version for proper lookup)\n            rendered_content: Final = self.prompt_manager.render(\n                prompt_id=prompt_id,\n                prompt_variables=prompt_variables,\n                version=prompt_version,\n            )\n\n            # Convert rendered content to chat messages\n            messages: Final = self._convert_to_messages(rendered_content)\n\n            # Extract model from metadata (if specified)\n            template_model: Final = template.model\n\n            # Extract optional parameters from metadata\n            optional_params: Final = self._extract_optional_params(template)\n\n            return PromptManagementClient(","sourceCodeStart":113,"sourceCodeEnd":149,"githubUrl":"https://github.com/BerriAI/litellm/blob/77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8/litellm/integrations/dotprompt/dotprompt_manager.py#L113-L149","documentation":"After resolving prompt_id, DotpromptManager calls self.prompt_manager.get_prompt(prompt_id, version=prompt_version); a None template means no matching prompt was found in the configured directory/prompt_data, and it raises ValueError naming the prompt and (if given) the version. The prompt sources are: <prompt_directory>/<prompt_id>.prompt files or in-memory prompt_data entries.","triggerScenarios":"File my_prompt.prompt absent from the configured directory; requesting version=3 when only the base prompt or version 2 exists; prompt_directory pointing at the wrong path (typo, relative path resolved from a different cwd); ID/file-name mismatch (file saved as my-prompt.prompt but requested as my_prompt).","commonSituations":"Deployments where the prompts directory isn't shipped into the container; prompts renamed during refactors; version pinning in config drifting from available versions; relative paths breaking under different working directories.","solutions":["Confirm the file exists at <prompt_directory>/<prompt_id>.prompt exactly matching the ID and extension","If a version is requested, verify that version exists (or drop prompt_version to fall back to base)","Print the resolved prompt_directory at startup and fix typos/paths; prefer absolute paths in containers","For prompt_data sources, verify the data dict actually contains the prompt_id key"],"exampleFix":"# before\nlitellm.global_prompt_directory = \"./promts\"   # typo: no such dir\nlitellm.completion(model=\"dotprompt/greeting\")    # ValueError: 'greeting' not found\n\n# after\nimport os\nlitellm.global_prompt_directory = os.path.abspath(\"./prompts\")\nassert os.path.exists(os.path.join(litellm.global_prompt_directory, \"greeting.prompt\"))\nlitellm.completion(model=\"dotprompt/greeting\")","handlingStrategy":"validation","validationCode":"import os\n\ndef prompt_exists(prompt_directory: str, prompt_id: str, version: int | None = None) -> bool:\n    candidates = [f\"{prompt_id}.v{version}.prompt\"] if version else []\n    candidates.append(f\"{prompt_id}.prompt\")\n    return any(os.path.isfile(os.path.join(prompt_directory, c)) for c in candidates)","typeGuard":"from typing import Any\n\ndef is_resolvable_prompt(manager: Any, prompt_id: str, version: int | None = None) -> bool:\n    \"\"\"True when the manager's store actually contains the prompt.\"\"\"\n    try:\n        return manager.get_prompt(prompt_id=prompt_id, version=version) is not None\n    except Exception:\n        return False","tryCatchPattern":"try:\n    client = manager.compile_prompt_helper(prompt_id, prompt_variables, dynamic_callback_params)\nexcept ValueError as e:\n    if \"not found in prompt directory\" in str(e):\n        raise KeyError(f\"missing prompt file for {prompt_id!r}; check prompt_directory and versions\") from e\n    raise","preventionTips":["Use absolute prompt_directory paths; verify files exist in a build/CI step","Keep a manifest test: every prompt_id referenced in config maps to an existing .prompt file","Treat version pinning like an API contract — update pins deliberately when files change"],"tags":["dotprompt","prompt-management","not-found","file-path","versioning"],"backgroundTag":"resource-not-found","analyzedSha":"77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8","analyzedAt":"2026-08-18T11:44:31.656Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}