HKUDS/Vibe-Trading · error · TypeError

artifact: cannot normalize a value of type {type(value).__na

Error message

artifact: cannot normalize a value of type {type(value).__name__!r} at path {path!r}; extend _flatten or pass a plain mapping / sequence / dataclass / Assumption / scalar

What it means

_flatten normalizes artifact inputs into hashable leaves for compute_input_hash. It accepts plain mappings, sequences, dataclasses, Assumption objects, and scalars; any other type (custom class, numpy array, datetime, set) cannot be canonicalized, so it raises a TypeError naming the path where the offending value sits.

Source

Thrown at agent/src/quantlib/valuation/artifact.py:493

        value = value.tolist()

    if isinstance(value, (list, tuple)):
        for index, item in enumerate(value):
            _flatten(item, f"{path}[{index}]", hash_leaves, readable_leaves, assumptions)
        return

    if dataclasses.is_dataclass(value) and not isinstance(value, type):
        for field in dataclasses.fields(value):
            _flatten(
                getattr(value, field.name),
                f"{path}.{field.name}",
                hash_leaves,
                readable_leaves,
                assumptions,
            )
        return

    raise TypeError(
        f"artifact: cannot normalize a value of type {type(value).__name__!r} at "
        f"path {path!r}; extend _flatten or pass a plain mapping / sequence / "
        "dataclass / Assumption / scalar"
    )


def _hash_leaves(hash_leaves: Mapping[str, str]) -> str:
    """Hash a completed ``path -> canonical string`` leaf set.

    Args:
        hash_leaves: Output of one or more :func:`_flatten` calls.

    Returns:
        A 64-character sha256 hex digest.
    """
    canonical = json.dumps(
        {"schema": _HASH_SCHEMA, "leaves": dict(hash_leaves)},
        sort_keys=True,

View on GitHub (pinned to 80ffdda44c)

Solutions

  1. Convert the value at the reported path to a supported type: primitives, lists/dicts/tuples, dataclasses, or Assumption.
  2. For datetimes use .isoformat(); for numpy scalars use .item(); for arrays convert to lists.
  3. If the type is a legitimate reusable input, extend _flatten to handle it.

Example fix

# before
build_dcf_artifact(..., extra={"as_of": some_datetime, "curve": np.array([...])})
# after
build_dcf_artifact(..., extra={"as_of": some_datetime.isoformat(), "curve": np.array([...]).tolist()})
Defensive patterns

Strategy: validation

Validate before calling

ALLOWED = (str, int, float, bool, type(None), list, tuple, dict)
def check_flattenable(value, path="root"):
    if isinstance(value, ALLOWED):
        return True
    if hasattr(value, "__dataclass_fields__"):
        return True
    raise TypeError(f"unflattenable {type(value).__name__} at {path}")

Type guard

def is_flattenable(value) -> bool:
    from dataclasses import is_dataclass
    return isinstance(value, (str, int, float, bool, type(None), list, tuple, dict)) or is_dataclass(value)

Try / catch

try:
    artifact = build_dcf_artifact(...)
except TypeError as e:
    if "cannot normalize" in str(e):
        # sanitize inputs (isoformat datetimes, .tolist() arrays) and retry
        ...
    raise

Prevention

When it happens

Trigger: Placing a custom Python object, a numpy array, a set, or a datetime inside the config/target/inputs passed to build_dcf_artifact / build_comps_artifact / build_three_statement_artifact; nested dicts containing such values at some path.

Common situations: Attaching raw model objects or numpy results to artifact inputs; incrementally adding new config fields with rich types; datetime fields added without converting to ISO strings.

Related errors


AI-assisted analysis of HKUDS/Vibe-Trading@80ffdda44c (2026-08-28). Data as JSON: /api/errors/28fb4dd997dbf9a2. Report an issue: GitHub.