TauricResearch/TradingAgents · error · ValueError

Date must be string or datetime object, got {type(date_input

Error message

Date must be string or datetime object, got {type(date_input)}

What it means

Raised by format_datetime_for_api() in tradingagents/dataflows/alpha_vantage_common.py when date_input is neither a str nor a datetime.datetime instance (e.g. a date, int, pandas.Timestamp-backed object, or None). It is a type-guard ValueError that fails fast before a malformed value reaches the Alpha Vantage URL builder.

Source

Thrown at tradingagents/dataflows/alpha_vantage_common.py:56

    """Convert various date formats to YYYYMMDDTHHMM format required by Alpha Vantage API."""
    if isinstance(date_input, str):
        # If already in correct format, return as-is
        if len(date_input) == 13 and 'T' in date_input:
            return date_input
        # Try to parse common date formats
        try:
            dt = datetime.strptime(date_input, "%Y-%m-%d")
            return dt.strftime("%Y%m%dT0000")
        except ValueError:
            try:
                dt = datetime.strptime(date_input, "%Y-%m-%d %H:%M")
                return dt.strftime("%Y%m%dT%H%M")
            except ValueError:
                raise ValueError(f"Unsupported date format: {date_input}") from None
    elif isinstance(date_input, datetime):
        return date_input.strftime("%Y%m%dT%H%M")
    else:
        raise ValueError(f"Date must be string or datetime object, got {type(date_input)}")

class AlphaVantageRateLimitError(VendorRateLimitError):
    """Raised when the Alpha Vantage API rate limit is exceeded."""
    pass

def _make_api_request(function_name: str, params: dict) -> dict | str:
    """Helper function to make API requests and handle responses.

    Raises:
        AlphaVantageRateLimitError: When API rate limit is exceeded
    """
    # Create a copy of params to avoid modifying the original
    api_params = params.copy()
    api_params.update({
        "function": function_name,
        "apikey": get_api_key(),
        "source": "trading_agents",
    })

View on GitHub (pinned to a33fd4c0f1)

Solutions

  1. Pass a datetime.datetime (convert dates with datetime.datetime.combine(d, datetime.time()) or datetime.datetime(d.year, d.month, d.day))
  2. Pass a plain 'YYYY-MM-DD' string, which the function parses itself
  3. Add an isinstance check or default in your caller so None/ints never reach this parameter

Example fix

# before
format_datetime_for_api(datetime.date(2025, 1, 15))
# -> ValueError: Date must be string or datetime object, got <class 'datetime.date'>

# after
from datetime import datetime, date, time
format_datetime_for_api(datetime.combine(date(2025, 1, 15), time()))  # datetime.datetime passes
# or simply
format_datetime_for_api("2025-01-15")
Defensive patterns

Strategy: type-guard

Validate before calling

from datetime import datetime, date

def coerce_date_input(value):
    """Return str/datetime or raise before the library does."""
    if isinstance(value, datetime):
        return value
    if isinstance(value, date):  # datetime.date -> midnight datetime
        return datetime(value.year, value.month, value.day)
    if isinstance(value, str) and value.strip():
        return value.strip()
    raise TypeError(f"date must be str or datetime, got {type(value).__name__}")

Type guard

from datetime import datetime

def is_str_or_datetime(v) -> bool:
    return isinstance(v, (str, datetime)) and not (isinstance(v, str) and not v)

Try / catch

try:
    format_datetime_for_api(d)
except ValueError as e:
    if "must be string or datetime" in str(e):
        d = coerce_date_input(d)  # repair and retry once
    else:
        raise

Prevention

When it happens

Trigger: Passing datetime.date (not datetime), a Unix epoch integer, None, or a pandas Timestamp that does not pass isinstance(x, datetime) to a date parameter consumed by this formatter.

Common situations: Calling with datetime.date.today() instead of datetime.datetime.now(); passing an epoch int from a data pipeline; passing a timezone/untyped value deserialized from JSON; forwarding None when a field is optional in the caller's schema.

Related errors


AI-assisted analysis of TauricResearch/TradingAgents@a33fd4c0f1 (2026-08-14). Data as JSON: /api/errors/a4937dc4140f883d. Report an issue: GitHub.