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
- Convert the value at the reported path to a supported type: primitives, lists/dicts/tuples, dataclasses, or Assumption.
- For datetimes use .isoformat(); for numpy scalars use .item(); for arrays convert to lists.
- 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
- Convert datetimes to .isoformat() and numpy values to .item()/.tolist() before putting them in artifact inputs.
- Keep artifact inputs to primitives plus dataclasses/Assumption.
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
- amount must be numeric, got {self.amount!r}
- metadata must be a mapping, got {type(self.metadata).__name_
- CashFlowSeries members must be CashFlow, got {type(item).__n
- rate must be numeric, got {self.rate!r}
- FxRateTable entries must be FxRate, got {type(entry).__name_
AI-assisted analysis of HKUDS/Vibe-Trading@80ffdda44c (2026-08-28).
Data as JSON: /api/errors/28fb4dd997dbf9a2.
Report an issue: GitHub.