ArchiveBox/ArchiveBox · error · ValueError

Tried to parse invalid date! {date}

Error message

Tried to parse invalid date! {date}

What it means

parse_date in archivebox/misc/util.py raises ValueError when the incoming value cannot be normalized into a datetime. There are two failure points: the value is not a str/int/datetime (falls to the final raise at line 421), or dateparser returns None for an unparseable string (the "invalid date string" raise). Callers like from_json, RSS parsing, and directory imports pass user- or external-supplied timestamps, so malformed input surfaces here.

Source

Thrown at archivebox/misc/util.py:421

            pass

        try:
            iso_date = normalized.replace("Z", "+00:00")
            parsed_date = datetime.fromisoformat(iso_date)
            if parsed_date.tzinfo is None:
                return parsed_date.replace(tzinfo=timezone.utc)
            return parsed_date.astimezone(timezone.utc)
        except ValueError:
            pass

        from dateparser import parse as dateparser

        parsed_date = dateparser(normalized, settings={"TIMEZONE": "UTC"})
        if parsed_date is None:
            raise ValueError(f"Tried to parse invalid date string! {date}")
        return parsed_date.astimezone(timezone.utc)

    raise ValueError(f"Tried to parse invalid date! {date}")


@enforce_types
def download_url(url: str, timeout: int | None = None, config=None, **config_kwargs) -> str:
    """Download the contents of a remote url and return the text"""

    import requests
    from w3lib.encoding import html_body_declared_encoding, http_content_type_encoding

    from archivebox.config.common import get_config

    config = config or get_config(**config_kwargs)
    timeout = timeout or config.TIMEOUT
    session = requests.Session()

    if config.COOKIES_FILE and Path(config.COOKIES_FILE).is_file():
        cookie_jar = http.cookiejar.MozillaCookieJar(config.COOKIES_FILE)
        cookie_jar.load(ignore_discard=True, ignore_expires=True)

View on GitHub (pinned to 74564b2822)

Solutions

  1. Inspect the {date} value in the message and fix the source data so it is a valid date string, int epoch, or datetime.
  2. Pre-validate with dateparser in the caller and skip or default entries whose date is None before calling parse_date.
  3. If epoch input, ensure it is an int (not float or numeric string); convert numeric strings with int()/float() first.
  4. Wrap calls in try/except ValueError when processing untrusted bulk imports so one bad record does not abort the run.

Example fix

// before
snapshot['timestamp'] = parse_date(row['saved_at'])
// after
raw = (row.get('saved_at') or '').strip()
snapshot['timestamp'] = parse_date(raw) if raw and dateparser.parse(raw) else None
Defensive patterns

Strategy: validation

Validate before calling

from dateparser import parse
def is_parseable_date(value) -> bool:
    return isinstance(value, (int,)) or (isinstance(value, str) and bool(parse(value)))

Type guard

def is_date_input(v) -> bool:
    return isinstance(v, (int, str)) and (isinstance(v, int) or parse(v) is not None)

Try / catch

try:
    dt = parse_date(raw)
except ValueError as e:
    log.warning("bad date: %s", e); dt = None

Prevention

When it happens

Trigger: Calling parse_date with a non-date string (e.g. 'N/A', empty string, a URL), a numeric type other than int/float epoch, or a datetime subclass handled upstream; also any string dateparser cannot interpret under UTC settings.

Common situations: Importing bookmarks/exports where a timestamp field is missing or filled with placeholder text; RSS feeds with malformed pubDates; JSON snapshots saved by older ArchiveBox versions with different date formats; passing a float epoch instead of int.

Related errors


AI-assisted analysis of ArchiveBox/ArchiveBox@74564b2822 (2026-08-28). Data as JSON: /api/errors/5982d87d3be4332c. Report an issue: GitHub.