OpenBMB/ChatDev · error · ValueError

Invalid function calling configuration payload

Error message

Invalid function calling configuration payload

What it means

Gemini provider _coerce_function_calling_config accepts only a genai_types.FunctionCallingConfig instance, a mode string (e.g. 'AUTO', 'ANY', 'NONE'), or a dict of FunctionCallingConfig kwargs. Any other payload type raises this ValueError while coercing tool_config for a Gemini agent.

Source

Thrown at runtime/node/agent/providers/gemini_provider.py:665

    def _coerce_tool_config(self, payload: Any) -> genai_types.ToolConfig:
        if isinstance(payload, genai_types.ToolConfig):
            return payload
        kwargs: Dict[str, Any] = {}
        if isinstance(payload, dict):
            fn_payload = payload.get("function_calling_config")
            if fn_payload:
                kwargs["function_calling_config"] = self._coerce_function_calling_config(fn_payload)
        return genai_types.ToolConfig(**kwargs)

    def _coerce_function_calling_config(self, payload: Any) -> genai_types.FunctionCallingConfig:
        if isinstance(payload, genai_types.FunctionCallingConfig):
            return payload
        if isinstance(payload, str):
            return genai_types.FunctionCallingConfig(mode=payload)
        if isinstance(payload, dict):
            return genai_types.FunctionCallingConfig(**payload)
        raise ValueError("Invalid function calling configuration payload")

    def _coerce_automatic_function_calling(self, payload: Any) -> Any:
        config_cls = getattr(genai_types, "AutomaticFunctionCallingConfig", None)
        if config_cls is None:
            raise ValueError("Automatic function calling config not supported in current SDK version")
        if isinstance(payload, config_cls):
            return payload
        if isinstance(payload, dict):
            return config_cls(**payload)
        raise ValueError("Invalid automatic function calling config payload")

    # ---------------------------------------------------------------------
    # Response parsing
    # ---------------------------------------------------------------------

    def _deserialize_response(self, response: Any) -> Message:
        candidate = self._select_primary_candidate(response)
        if not candidate:

View on GitHub (pinned to 4fb2db0ea9)

Solutions

  1. Pass a plain mode string like 'AUTO' or 'ANY'
  2. Or pass a dict of valid FunctionCallingConfig fields, e.g. {'mode': 'ANY', 'allowed_function_names': [...]}, dropping unknown keys before passing
  3. Ensure you're sending a str or dict, not a custom object; sanitize converted configs from other providers

Example fix

# before
tool_config = {'function_calling_config': {'mode': 'ANY', 'tool_choice': 'auto'}}

# after
tool_config = {'function_calling_config': {'mode': 'ANY', 'allowed_function_names': ['search']}}
Defensive patterns

Strategy: type-guard

Validate before calling

def is_valid_fcc(payload) -> bool:
    if isinstance(payload, str):
        return payload in ('AUTO', 'ANY', 'NONE')
    if isinstance(payload, dict):
        valid = {'mode', 'allowed_function_names'}
        return set(payload) <= valid
    return hasattr(payload, 'mode')  # SDK instance

if not is_valid_fcc(tool_config.get('function_calling_config')):
    tool_config['function_calling_config'] = 'AUTO'

Type guard

def is_valid_fcc(payload) -> bool:
    if isinstance(payload, str):
        return payload in ('AUTO', 'ANY', 'NONE')
    if isinstance(payload, dict):
        return set(payload) <= {'mode', 'allowed_function_names'}
    return hasattr(payload, 'mode')

Try / catch

try:
    agent = build_gemini_agent(cfg)
except ValueError as e:
    if 'Invalid function calling configuration payload' in str(e):
        cfg.tool_config['function_calling_config'] = 'AUTO'
        agent = build_gemini_agent(cfg)
    else:
        raise

Prevention

When it happens

Trigger: Passing tool_config.function_calling_config as a non-string/dict object (e.g. a custom dataclass, a Pydantic model, a list, or None-labeled placeholder), or a dict containing keys that don't exist on FunctionCallingConfig (which surfaces similarly during coercion).

Common situations: Translating configs between providers (OpenAI tool choice objects passed straight through); SDK version differences where FunctionCallingConfig moved; YAML configs feeding arbitrary objects into function_calling_config.

Related errors


AI-assisted analysis of OpenBMB/ChatDev@4fb2db0ea9 (2026-08-27). Data as JSON: /api/errors/8f9f41109d0c1ff5. Report an issue: GitHub.