run-llama/llama_index · error · ValueError

Prompt key {key} cannot contain ':'.

Error message

Prompt key {key} cannot contain ':'.

What it means

PromptMixin._validate_prompts (prompts/mixin.py) rejects any prompt key containing ':' in the dict returned by _get_prompts(). ':' is the reserved namespace separator used by get_prompts() to flatten sub-module prompts into keys like 'response_synthesizer:text_qa_template', so a raw ':' inside your own key would make the flattened namespace ambiguous and un-parseable by update_prompts().

Source

Thrown at llama-index-core/llama_index/core/prompts/mixin.py:34

    """
    Prompt mixin.

    This mixin is used in other modules, like query engines, response synthesizers.
    This shows that the module supports getting, setting prompts,
    both within the immediate module as well as child modules.

    """

    def _validate_prompts(
        self,
        prompts_dict: PromptDictType,
        module_dict: PromptMixinType,
    ) -> None:
        """Validate prompts."""
        # check if prompts_dict, module_dict has restricted ":" token
        for key in prompts_dict:
            if ":" in key:
                raise ValueError(f"Prompt key {key} cannot contain ':'.")

        for key in module_dict:
            if ":" in key:
                raise ValueError(f"Prompt key {key} cannot contain ':'.")

    def get_prompts(self) -> Dict[str, BasePromptTemplate]:
        """Get a prompt."""
        prompts_dict = self._get_prompts()
        module_dict = self._get_prompt_modules()
        self._validate_prompts(prompts_dict, module_dict)

        # avoid modifying the original dict
        all_prompts = deepcopy(prompts_dict)
        for module_name, prompt_module in module_dict.items():
            # append module name to each key in sub-modules by ":"
            for key, prompt in prompt_module.get_prompts().items():
                all_prompts[f"{module_name}:{key}"] = prompt
        return all_prompts

View on GitHub (pinned to afd0fef371)

Solutions

  1. Rename the key to remove ':' — use '_', '-', or '.' instead: {'my_prompt': ...} or {'agent.system': ...}.
  2. If the intent was namespacing, model it properly: return the prompt from a sub-component and let get_prompts() build the 'module:key' name for you.
  3. If keys come from external config, sanitize them (key.replace(':', '_')) when building the prompts dict.
  4. Add a unit test asserting no key in _get_prompts()/_get_prompt_modules() contains ':' so regressions surface at test time, not at runtime.

Example fix

# before
class MyQueryEngine(CustomQueryEngine):
    def _get_prompts(self):
        return {"retriever:top_k": self.retriever_prompt}  # -> ValueError

# after
class MyQueryEngine(CustomQueryEngine):
    def _get_prompts(self):
        return {"retriever_top_k": self.retriever_prompt}  # no ':' anywhere
Defensive patterns

Strategy: validation

Validate before calling

def validate_prompt_keys(prompts: dict) -> None:
    bad = [k for k in prompts if ":" in k]
    if bad:
        raise KeyError(f"prompt keys must not contain ':' (reserved): {bad}")

# in your component:
# validate_prompt_keys(self._get_prompts())

Type guard

def has_clean_prompt_keys(prompts: dict) -> bool:
    return all(":" not in k for k in prompts)

Prevention

When it happens

Trigger: Implementing a component's _get_prompts() (or _get_prompt_modules()) and returning a dict whose key literally contains ':', e.g. {'my:prompt': SomeTemplate}. The error fires the moment get_prompts() is called on the component — including when it is embedded in a query engine / index whose get_prompts() recurses into it.

Common situations: Custom query engines or LLMs added to the codebase with ad-hoc prompt names that embed paths ('agent:system'), copy-pasted prompt identifiers from config files, or dynamically generated keys joined with ':'. Surfaces as soon as the user calls engine.get_prompts() or passes the component into a higher-level llama-index pipeline.

Related errors


AI-assisted analysis of run-llama/llama_index@afd0fef371 (2026-08-15). Data as JSON: /api/errors/7b244a16d2980df7. Report an issue: GitHub.