{"record":{"id":"c85dab6ef18891f5","repo":"BerriAI/litellm","slug":"either-prompt-directory-or-prompt-data-must-be-set","errorCode":null,"errorMessage":"Either prompt_directory or prompt_data must be set before using dotprompt manager. Set litellm.global_prompt_directory, initialize with prompt_directory parameter, or provide prompt_data.","messagePattern":"Either prompt_directory or prompt_data must be set before using dotprompt manager\\. Set litellm\\.global_prompt_directory, initialize with prompt_directory parameter, or provide prompt_data\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"litellm/integrations/dotprompt/dotprompt_manager.py","lineNumber":73,"sourceCode":"            self.prompt_data = json.loads(prompt_data)\n        else:\n            self.prompt_data = prompt_data or {}\n\n        self._prompt_manager: PromptManager | None = None\n        self.prompt_file = prompt_file\n        self.prompt_id = prompt_id\n\n    @property\n    def integration_name(self) -> str:\n        \"\"\"Integration name used in model names like 'dotprompt/gpt-4'.\"\"\"\n        return \"dotprompt\"\n\n    @property\n    def prompt_manager(self) -> PromptManager:\n        \"\"\"Lazy-load the prompt manager.\"\"\"\n        if self._prompt_manager is None:\n            if self.prompt_directory is None and not self.prompt_data and not self.prompt_file:\n                raise ValueError(\n                    \"Either prompt_directory or prompt_data must be set before using dotprompt manager. \"\n                    \"Set litellm.global_prompt_directory, initialize with prompt_directory parameter, or provide prompt_data.\"\n                )\n            self._prompt_manager = PromptManager(\n                prompt_directory=self.prompt_directory,\n                prompt_data=self.prompt_data,\n                prompt_file=self.prompt_file,\n                prompt_id=self.prompt_id,\n            )\n        return self._prompt_manager\n\n    def should_run_prompt_management(\n        self,\n        prompt_id: str | None,\n        prompt_spec: PromptSpec | None,\n        dynamic_callback_params: StandardCallbackDynamicParams,\n    ) -> bool:\n        \"\"\"","sourceCodeStart":55,"sourceCodeEnd":91,"githubUrl":"https://github.com/BerriAI/litellm/blob/77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8/litellm/integrations/dotprompt/dotprompt_manager.py#L55-L91","documentation":"The dotprompt integration's prompt_manager property lazily constructs a PromptManager on first use and requires one of prompt_directory, prompt_data, or prompt_file to be configured — globally (litellm.global_prompt_directory), at init, or per request. If none is set, it raises this ValueError the moment a dotprompt model is first used, not at startup.","triggerScenarios":"Calling a completion with model=\"dotprompt/gpt-4\" (or any dotprompt-prefixed route) without ever setting litellm.global_prompt_directory, without prompt_directory at DotpromptManager init, and without per-request prompt_data/prompt_file.","commonSituations":"Enabling the dotprompt integration and assuming prompts load from a default ./prompts directory; config that sets the directory on a different manager instance than the one serving requests; ordering issues where the model call happens before the global is assigned.","solutions":["Set litellm.global_prompt_directory = '/abs/path/to/prompts' before the first dotprompt call","Or pass prompt_directory when constructing the DotpromptManager","Or supply prompt_data / prompt_file per request so no directory is needed"],"exampleFix":"# before\nimport litellm\nlitellm.completion(model=\"dotprompt/gpt-4\", messages=[])  # ValueError: no source configured\n\n# after\nimport litellm\nlitellm.global_prompt_directory = \"./prompts\"   # contains greeting.prompt\nlitellm.completion(model=\"dotprompt/gpt-4:generate\", messages=[])","handlingStrategy":"validation","validationCode":"import os\nimport litellm\n\ndef dotprompt_ready() -> bool:\n    mgr = getattr(litellm, \"global_prompt_directory\", None)\n    return bool(mgr and os.path.isdir(mgr))\n\n# before the first call:\n# assert dotprompt_ready(), \"set litellm.global_prompt_directory before dotprompt models\"","typeGuard":"from typing import Any\n\ndef has_prompt_source(manager: Any) -> bool:\n    \"\"\"Manager can resolve prompts only with one of these set.\"\"\"\n    return bool(getattr(manager, \"prompt_directory\", None) or getattr(manager, \"prompt_data\", None) or getattr(manager, \"prompt_file\", None))","tryCatchPattern":null,"preventionTips":["Set litellm.global_prompt_directory once at process start, before any dotprompt model call","Smoke-test one dotprompt completion at deploy time to force the lazy init early","Ship the prompts directory in the container image and reference it by absolute path"],"tags":["dotprompt","prompt-management","configuration","lazy-initialization"],"backgroundTag":"missing-required-config","analyzedSha":"77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8","analyzedAt":"2026-08-18T11:44:31.656Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}