assafelovic/gpt-researcher · error · ValueError

Cannot convert to any of

Error message

Cannot convert {env_value} to any of {args}

What it means

Config.convert_env_value tries each type in an Optional/Union type hint in turn; when no branch can convert the raw env string, it raises this aggregated ValueError. It is the fallback for Union types where every candidate conversion failed.

Solutions

  1. Set the env var to a valid literal for the annotated type (true/false for bool, digits for int/float)
  2. Remove the variable to use the default
  3. Check the Config attribute type hints for the key named in the message

Example fix

# before
FAST_TOKEN_LIMIT=unlimited
# after
FAST_TOKEN_LIMIT=4000
Defensive patterns

Strategy: validation

Validate before calling

def coerce(env_val, types):
    for t in types:
        try:
            return Config.convert_env_value("k", env_val, t)
        except ValueError:
            pass
    raise ValueError(env_val)
# preflight any Optional[int] var:
coerce(os.getenv('FAST_TOKEN_LIMIT','4000'), (int, type(None)))

Try / catch

try:
    cfg = Config()
except ValueError as e:
    if "Cannot convert" in str(e):
        print('Bad env value:', e); exit(2)
    raise

Prevention

When it happens

Trigger: An env var annotated Optional[int] set to 'abc', or Optional[bool] set to 'maybe'—each inner conversion raises and the loop exhausts, producing this message.

Common situations: Hand-edited .env files with non-numeric values for numeric settings; booleans set to 'yeah'; JSON-ish values on scalar fields.

Related errors


AI-assisted analysis of assafelovic/gpt-researcher@6f998577d5 (2026-08-28). Data as JSON: /api/errors/f93e3b8ce6a70438. Report an issue: GitHub.

Appendix: source

Thrown at gpt_researcher/config/config.py:277

        """Convert environment variable to the appropriate type based on the type hint."""
        origin = get_origin(type_hint)
        args = get_args(type_hint)

        if origin is Union:
            # Handle Union types (e.g., Union[str, None] / Optional[str]).
            # Check the None sentinel BEFORE non-None args: for Optional[str],
            # str conversion never raises, so looping str-first permanently
            # shadowed the none/null/"" → None branch (see issue #1899).
            if type(None) in args and env_value.lower() in ("none", "null", ""):
                return None
            for arg in args:
                if arg is type(None):
                    continue
                try:
                    return Config.convert_env_value(key, env_value, arg)
                except ValueError:
                    continue
            raise ValueError(f"Cannot convert {env_value} to any of {args}")

        if type_hint is bool:
            return env_value.lower() in ("true", "1", "yes", "on")
        elif type_hint is int:
            return int(env_value)
        elif type_hint is float:
            return float(env_value)
        elif type_hint in (str, Any):
            return env_value
        elif type_hint is list or origin is list or origin is List:
            # Env values are often hand-edited (trailing commas, single quotes).
            # Bare `list` has get_origin(None); typing.List[...] has origin list.
            try:
                value = json_repair.loads(env_value)
            except Exception as exc:
                raise ValueError(f"Cannot convert {env_value} to list") from exc
            if not isinstance(value, list):
                raise ValueError(f"Cannot convert {env_value} to list")

View on GitHub (pinned to 6f998577d5)