deepset-ai/haystack · error

The prompt must not have any variables, only instructions on

Error message

The prompt must not have any variables, only instructions on how to extract the content of the the image-based document. Found {','.join(variables)} in the prompt.

What it means

LLMDocumentContentExtractor renders its prompt template with the image document content only; the user-supplied prompt must therefore contain no Jinja variables. Any undeclared variable found by parsing the template triggers ValueError.

Source

Thrown at haystack/components/extractors/image/llm_document_content_extractor.py:251

        Deserializes the component from a dictionary.

        :param data:
            Dictionary with serialized data.
        :returns:
            An instance of the component.
        """
        init_params = data.get("init_parameters", {})
        deserialize_chatgenerator_inplace(init_params, key="chat_generator")

        return default_from_dict(cls, data)

    @staticmethod
    def _validate_prompt_no_variables(prompt: str) -> None:
        ast = SandboxedEnvironment().parse(prompt)
        template_variables = meta.find_undeclared_variables(ast)
        variables = list(template_variables)
        if variables:
            raise ValueError(
                f"The prompt must not have any variables, only instructions on how to extract the content of the "
                f"the image-based document. Found {','.join(variables)} in the prompt."
            )

    @staticmethod
    def _process_response(response_text: str) -> tuple[str | None, dict[str, Any], str | None]:
        """
        Parse LLM response. Returns (content, meta_updates, error).

        - Plain string (non-JSON): use entire response as document content;
        - Valid JSON object: use key ``document_content`` for Document.content and all other keys for Document.metadata;
        - Valid JSON but not an object (e.g. array or primitive), report an error;
        """
        try:
            parsed = _parse_dict_from_json(response_text, raise_on_failure=True)
        except json.JSONDecodeError:
            return response_text, {}, None
        except ValueError:

View on GitHub (pinned to e318778c9b)

Solutions

  1. Rewrite the prompt as plain instructions with no {{ }} variables, e.g. "Extract all text content from the image"
  2. Remove any variable placeholders copied from other extractor components
  3. If you need variable substitution, use a different component (e.g. PromptBuilder) instead

Example fix

// before
extractor = LLMDocumentContentExtractor(prompt="Extract the content of {{ document }}")
// after
extractor = LLMDocumentContentExtractor(prompt="Extract all textual content from the provided image")
Defensive patterns

Strategy: validation

Validate before calling

from jinja2 import meta, Environment
vars_ = meta.find_undeclared_variables(Environment().parse(prompt))
if vars_:
    raise ValueError(f"Prompt must not contain variables: {vars_}")

Prevention

When it happens

Trigger: Passing a prompt like "Extract the text from {{ document }}" to LLMDocumentContentExtractor(prompt=...); any prompt containing {{ ... }} placeholders fails _validate_prompt_no_variables at construction.

Common situations: Copying a prompt from LLMMetadataExtractor (which requires a 'document' variable) into the image extractor; templated prompts reused across components.

Related errors


AI-assisted analysis of deepset-ai/haystack@e318778c9b (2026-08-30). Data as JSON: /api/errors/763111ef717250ee. Report an issue: GitHub.