BerriAI/litellm · error · Exception

'argilla_transformation_object' must be a dictionary, to…

Error message

'argilla_transformation_object' must be a dictionary, to log your payload to Argilla.

What it means

`litellm.argilla_transformation_object` must be a dict that maps Argilla dataset field names to LiteLLM payload keys. `validate_argilla_transformation_object` runs during ArgillaLogger construction and rejects anything that is not a dict (e.g. a list, string, or JSON-decoded array) because it iterates `.values()` to check each mapping.

Solutions

  1. Change the value to a dict mapping Argilla field -> payload key, e.g. `litellm.argilla_transformation_object = {"prompt": "messages", "response": "response"}`
  2. If loading from config files, print `type(litellm.argilla_transformation_object)` right before the callback fires to confirm it is a dict
  3. Ensure every VALUE in the dict is one of SUPPORTED_PAYLOAD_FIELDS (currently "messages" or "response") so the next validation passes

Example fix

# before
litellm.argilla_transformation_object = ["messages", "response"]  # list -> raises

# after
litellm.argilla_transformation_object = {
    "prompt": "messages",
    "response": "response",
}
Defensive patterns

Strategy: type-guard

Validate before calling

from litellm.types.integrations.argilla import SUPPORTED_PAYLOAD_FIELDS

def build_transformation_object(mapping: dict) -> dict:
    if not isinstance(mapping, dict):
        raise TypeError(f"expected dict, got {type(mapping).__name__}")
    bad = [v for v in mapping.values() if v not in SUPPORTED_PAYLOAD_FIELDS]
    if bad:
        raise ValueError(f"unsupported payload keys: {bad}; allowed: {SUPPORTED_PAYLOAD_FIELDS}")
    return mapping

Type guard

def is_argilla_mapping(obj: object) -> bool:
    return isinstance(obj, dict) and all(isinstance(k, str) and isinstance(v, str) for k, v in obj.items())

Try / catch

try:
    ArgillaLogger()  # or trigger via callbacks
except Exception as e:
    msg = str(e)
    if "must be a dictionary" in msg:
        # fix shape then retry init once
        litellm.argilla_transformation_object = dict.fromkeys(
            litellm.argilla_transformation_object or [], "response"
        )
    else:
        raise

Prevention

When it happens

Trigger: Assigning `litellm.argilla_transformation_object = ["messages", "response"]` (a list) or `= "messages"` (a string) or loading it from YAML/JSON that parses to a list, then triggering ArgillaLogger initialization with `litellm.callbacks = ["argilla"]`.

Common situations: Hand-writing the config as a list of fields instead of a mapping; a YAML config where indentation turns the intended dict into a list of strings; programmatic config built by appending field names.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18). Data as JSON: /api/errors/f7ca65b30a5796d4. Report an issue: GitHub.

Appendix: source

Thrown at litellm/integrations/argilla.py:74

            argilla_base_url=argilla_base_url,
        )
        self.sampling_rate: float = (
            float(os.getenv("ARGILLA_SAMPLING_RATE"))
            if os.getenv("ARGILLA_SAMPLING_RATE") is not None and os.getenv("ARGILLA_SAMPLING_RATE").strip().isdigit()
            else 1.0
        )

        self.async_httpx_client = get_async_httpx_client(llm_provider=httpxSpecialProvider.LoggingCallback)
        _batch_size: Final = os.getenv("ARGILLA_BATCH_SIZE", None) or litellm.argilla_batch_size
        if _batch_size:
            self.batch_size = int(_batch_size)
        asyncio.create_task(self.periodic_flush())
        self.flush_lock = asyncio.Lock()
        super().__init__(**kwargs, flush_lock=self.flush_lock)

    def validate_argilla_transformation_object(self, argilla_transformation_object: dict[str, Any]):
        if not isinstance(argilla_transformation_object, dict):
            raise Exception("'argilla_transformation_object' must be a dictionary, to log your payload to Argilla.")

        for v in argilla_transformation_object.values():
            if v not in SUPPORTED_PAYLOAD_FIELDS:
                raise Exception(
                    f"All values in argilla_transformation_object must be a key in SUPPORTED_PAYLOAD_FIELDS, {v} is not a valid key."
                )

    def get_credentials_from_env(
        self,
        argilla_api_key: str | None,
        argilla_dataset_name: str | None,
        argilla_base_url: str | None,
    ) -> ArgillaCredentialsObject:
        _credentials_api_key: Final = argilla_api_key or os.getenv("ARGILLA_API_KEY")
        if _credentials_api_key is None:
            raise Exception("Invalid Argilla API Key given. _credentials_api_key=None.")

        _credentials_base_url: Final = argilla_base_url or os.getenv("ARGILLA_BASE_URL") or "http://localhost:6900/"

View on GitHub (pinned to 77b7c6c40c)