{"record":{"id":"6fb665a8ac6ad04c","repo":"BerriAI/litellm","slug":"prompt-id-is-required-for-arize-phoenix-prompt-man","errorCode":null,"errorMessage":"prompt_id is required for Arize Phoenix prompt manager","messagePattern":"prompt_id is required for Arize Phoenix prompt manager","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"litellm/integrations/arize/arize_phoenix_prompt_manager.py","lineNumber":386,"sourceCode":"        self,\n        prompt_id: str | None,\n        prompt_spec: PromptSpec | None,\n        prompt_variables: dict | None,\n        dynamic_callback_params: StandardCallbackDynamicParams,\n        prompt_label: str | None = None,\n        prompt_version: int | None = None,\n    ) -> PromptManagementClient:\n        \"\"\"\n        Compile an Arize Phoenix prompt template into a PromptManagementClient structure.\n\n        This method:\n        1. Loads the prompt version from Arize Phoenix\n        2. Renders it with the provided variables\n        3. Returns formatted chat messages\n        4. Extracts model and optional parameters from metadata\n        \"\"\"\n        if prompt_id is None:\n            raise ValueError(\"prompt_id is required for Arize Phoenix prompt manager\")\n        try:\n            # Load the prompt from Arize Phoenix if not already loaded\n            if prompt_id not in self.prompt_manager.prompts:\n                self.prompt_manager._load_prompt_from_arize(prompt_id)\n\n            # Get the rendered messages and metadata\n            rendered_messages, prompt_metadata = self.get_prompt_template(prompt_id, prompt_variables)\n\n            # Extract model from metadata (if specified)\n            template_model: Final = prompt_metadata.get(\"model\")\n\n            # Extract optional parameters from metadata\n            optional_params: Final = {}\n            for param in [\n                \"temperature\",\n                \"max_tokens\",\n                \"top_p\",\n                \"frequency_penalty\",","sourceCodeStart":368,"sourceCodeEnd":404,"githubUrl":"https://github.com/BerriAI/litellm/blob/6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d/litellm/integrations/arize/arize_phoenix_prompt_manager.py#L368-L404","documentation":"The synchronous Arize Phoenix compile helper (_compile_prompt_helper) requires a prompt_id because Phoenix identifies prompts solely by ID. It raises ValueError immediately when prompt_id is None, before any Phoenix API call is attempted. This is a caller-side contract violation: the routing layer was unable to extract a prompt_id from the request.","triggerScenarios":"Invoking the Phoenix prompt integration without a prompt_id, e.g. model='phoenix/' with an empty ID segment, or litellm_params that omit prompt_id while bitbucket/prompt spec fields are absent; a prompt_spec supplied instead of prompt_id (Phoenix does not support spec-based lookup); programmatic calls to _compile_prompt_helper(prompt_id=None, ...).","commonSituations":"Malformed model string 'phoenix/' (trailing slash with no ID); copy-pasting a config from another prompt integration that passes a spec instead of an ID; forgetting to set prompt_id in the proxy's model config for a Phoenix-based deployment.","solutions":["Set the prompt_id: use model='phoenix/<prompt_id>' or add prompt_id to litellm_params / the proxy model settings","Validate the model string format before routing (non-empty ID after 'phoenix/')","If you meant to use a prompt spec instead of an ID, that flow is not supported by the Phoenix manager — switch to a supported integration or supply the ID"],"exampleFix":"# before\nparams = {\"model\": \"phoenix/\"}  # empty prompt_id -> ValueError\n\n# after\nparams = {\"model\": \"phoenix/summarize-v2\"}  # or params[\"prompt_id\"] = \"summarize-v2\"","handlingStrategy":"validation","validationCode":"def resolve_phoenix_model(prompt_id: str | None) -> str:\n    if not prompt_id or not prompt_id.strip():\n        raise ValueError(\"prompt_id must be a non-empty string\")\n    return f\"phoenix/{prompt_id}\"\n\nmodel = resolve_phoenix_model(os.getenv(\"PHOENIX_PROMPT_ID\"))","typeGuard":"def has_prompt_id(params: dict) -> bool:\n    pid = params.get(\"prompt_id\") or (params.get(\"model\", \"\").split(\"/\", 1)[1] if params.get(\"model\", \"\").startswith(\"phoenix/\") else None)\n    return isinstance(pid, str) and len(pid.strip()) > 0","tryCatchPattern":"try:\n    litellm.completion(model=f\"phoenix/{prompt_id}\", messages=[...])\nexcept ValueError as e:\n    if \"prompt_id is required\" in str(e):\n        raise ValueError(\"Configure PHOENIX_PROMPT_ID before calling Phoenix-backed models\") from e\n    raise","preventionTips":["Assert a non-empty prompt ID at config load time","Fail fast on unset env vars that feed model strings (os.environ[...] not os.getenv(..., ''))","Add a unit test that every phoenix/* model in your config has a non-empty ID segment"],"tags":["arize-phoenix","prompt-management","validation","valueerror"],"backgroundTag":null,"analyzedSha":"6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d","analyzedAt":"2026-08-15T07:12:03.035Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}