D4Vinci/Scrapling · error · TypeError

Invalid argument type: {e}

Error message

Invalid argument type: {e}

What it means

validate() converts msgspec ValidationError into TypeError('Invalid argument type: ...') whenever kwargs passed to a session constructor or fetch() do not match the config Struct's types. The chained msgspec message names the exact offending field and expected type, so read the full exception text.

Source

Thrown at scrapling/engines/_browsers/_validators.py:252

    defaults = models_default_values[model]
    return {k: v for k, v in params.items() if k not in defaults or v != defaults[k]}


@overload
def validate(params: Dict, model: type[StealthConfig]) -> StealthConfig: ...


@overload
def validate(params: Dict, model: type[PlaywrightConfig]) -> PlaywrightConfig: ...


def validate(params: Dict, model: type[PlaywrightConfig] | type[StealthConfig]) -> PlaywrightConfig | StealthConfig:
    try:
        # Filter out params with the default values (no need to validate them) to speed up validation
        filtered = _filter_defaults(params, model.__name__)
        return convert(filtered, model)
    except ValidationError as e:
        raise TypeError(f"Invalid argument type: {e}") from e

View on GitHub (pinned to 5d213a2d47)

Solutions

  1. Read the appended msgspec message in the traceback — it names the field, expected type, and constraint that failed
  2. Coerce config values before passing: int()/bool()/proper dict structures, especially values loaded from files/ENV
  3. Check field constraints: max_pages 1-50, retries 1-10, retry_delay >= 0, wait_selector_state in the allowed states

Example fix

# before (config loaded from JSON, all strings)
session = StealthySession(headless='true', max_pages='3', cookies='session=abc')

# after
cfg = json.load(open('config.json'))
session = StealthySession(
    headless=bool(cfg['headless']),
    max_pages=int(cfg['max_pages']),
    cookies=[{'name': 'session', 'value': 'abc', 'domain': 'example.com', 'path': '/'}],
)
Defensive patterns

Strategy: try-catch

Validate before calling

# coerce before constructing the session
def sanitize(cfg: dict) -> dict:
    if 'headless' in cfg: cfg['headless'] = bool(cfg['headless'])
    if 'max_pages' in cfg: cfg['max_pages'] = int(cfg['max_pages'])
    if 'retries' in cfg: cfg['retries'] = int(cfg['retries'])
    assert 1 <= cfg.get('max_pages', 1) <= 50
    assert 1 <= cfg.get('retries', 3) <= 10
    return cfg

Type guard

def kwargs_match_config(cfg: dict) -> bool:
    try:
        convert({k: v for k, v in cfg.items()}, StealthConfig)
        return True
    except ValidationError:
        return False

Try / catch

from msgspec import ValidationError
try:
    session = StealthySession(**cfg)
except TypeError as e:
    if 'Invalid argument type' in str(e):
        # e.__cause__ carries msgspec's field-level detail
        log.error('config type error: %s', e.__cause__)
        raise
    raise

Prevention

When it happens

Trigger: Passing headless='yes' (string instead of bool), cookies='a=b' (string instead of a list of cookie dicts), max_pages='3' (string), unknown-typed proxy values, or any kwarg whose declared type in PlaywrightConfig/StealthConfig mismatches — including constraint violations like max_pages=0 (must be 1..50) or retries=20 (must be 1..10).

Common situations: Loading config from JSON/YAML/ENV where everything arrives as strings; passing Python primitives where msgspec Structs/typed sequences are required; boundary constraint violations (max_pages, retries, retry_delay).

Related errors


AI-assisted analysis of D4Vinci/Scrapling@5d213a2d47 (2026-08-14). Data as JSON: /api/errors/cc7e04e68864b773. Report an issue: GitHub.