OpenBMB/ChatDev · error · ConfigError

cache_ttl must be numeric

Error message

cache_ttl must be numeric

What it means

Raised when the 'cache_ttl' key of a tooling config is present but not numeric (int/float accepted). cache_ttl controls how long tool results are cached; the deserializer refuses non-numeric values rather than guessing.

Source

Thrown at entity/configs/node/tooling.py:387

                raise ConfigError("headers must be a mapping", extend_path(path, "headers"))
            headers = {str(k): str(v) for k, v in headers_raw.items()}

        timeout_value = mapping.get("timeout")
        timeout: float | None
        if timeout_value is None:
            timeout = None
        elif isinstance(timeout_value, (int, float)):
            timeout = float(timeout_value)
        else:
            raise ConfigError("timeout must be numeric", extend_path(path, "timeout"))

        cache_ttl_value = mapping.get("cache_ttl", 0.0)
        if cache_ttl_value is None:
            cache_ttl = 0.0
        elif isinstance(cache_ttl_value, (int, float)):
            cache_ttl = float(cache_ttl_value)
        else:
            raise ConfigError("cache_ttl must be numeric", extend_path(path, "cache_ttl"))

        tool_sources_raw = mapping.get("tool_sources")
        tool_sources: List[str] | None = None
        if tool_sources_raw is not None:
            entries = ensure_list(tool_sources_raw)
            normalized: List[str] = []
            for idx, entry in enumerate(entries):
                if not isinstance(entry, str):
                    raise ConfigError(
                        "tool_sources must be a list of strings",
                        extend_path(path, f"tool_sources[{idx}]"),
                    )
                value = entry.strip()
                if value:
                    normalized.append(value)
            tool_sources = normalized
        else:
            tool_sources = ["mcp_tools"]

View on GitHub (pinned to 4fb2db0ea9)

Solutions

  1. Make cache_ttl a number (60 or 0.5) or drop it / set null for the 0.0 default
  2. Coerce with float() before from_dict if the value is externally sourced
  3. Add schema validation for numeric fields in your config pipeline

Example fix

# before
cache_ttl: "60"
# after
cache_ttl: 60
Defensive patterns

Strategy: validation

Validate before calling

v = cfg.get("cache_ttl", 0.0)
assert v is None or isinstance(v, (int, float)) and not isinstance(v, bool)

Type guard

def valid_ttl(v) -> bool:
    return v is None or (isinstance(v, (int, float)) and not isinstance(v, bool))

Try / catch

try:
    obj = from_dict(mapping)
except ConfigError as e:
    log_config_error(e)  # message includes JSON path to cache_ttl

Prevention

When it happens

Trigger: Tooling config mapping with cache_ttl: "60" or cache_ttl: [60] passed to from_dict; YAML files where the TTL is quoted.

Common situations: Copy-pasted example configs with quoted numbers; environment-variable interpolation that yields strings (cache_ttl: ${TOOL_TTL}).

Related errors


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