{"record":{"id":"28fb4dd997dbf9a2","repo":"HKUDS/Vibe-Trading","slug":"artifact-cannot-normalize-a-value-of-type-type-v","errorCode":null,"errorMessage":"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","messagePattern":"artifact: cannot normalize a value of type (.+?) at path (.+?); extend _flatten or pass a plain mapping / sequence / dataclass / Assumption / scalar","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"agent/src/quantlib/valuation/artifact.py","lineNumber":493,"sourceCode":"        value = value.tolist()\n\n    if isinstance(value, (list, tuple)):\n        for index, item in enumerate(value):\n            _flatten(item, f\"{path}[{index}]\", hash_leaves, readable_leaves, assumptions)\n        return\n\n    if dataclasses.is_dataclass(value) and not isinstance(value, type):\n        for field in dataclasses.fields(value):\n            _flatten(\n                getattr(value, field.name),\n                f\"{path}.{field.name}\",\n                hash_leaves,\n                readable_leaves,\n                assumptions,\n            )\n        return\n\n    raise TypeError(\n        f\"artifact: cannot normalize a value of type {type(value).__name__!r} at \"\n        f\"path {path!r}; extend _flatten or pass a plain mapping / sequence / \"\n        \"dataclass / Assumption / scalar\"\n    )\n\n\ndef _hash_leaves(hash_leaves: Mapping[str, str]) -> str:\n    \"\"\"Hash a completed ``path -> canonical string`` leaf set.\n\n    Args:\n        hash_leaves: Output of one or more :func:`_flatten` calls.\n\n    Returns:\n        A 64-character sha256 hex digest.\n    \"\"\"\n    canonical = json.dumps(\n        {\"schema\": _HASH_SCHEMA, \"leaves\": dict(hash_leaves)},\n        sort_keys=True,","sourceCodeStart":475,"sourceCodeEnd":511,"githubUrl":"https://github.com/HKUDS/Vibe-Trading/blob/80ffdda44c5c4db0dd84d70e051cca591cea67df/agent/src/quantlib/valuation/artifact.py#L475-L511","documentation":"_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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"# before\nbuild_dcf_artifact(..., extra={\"as_of\": some_datetime, \"curve\": np.array([...])})\n# after\nbuild_dcf_artifact(..., extra={\"as_of\": some_datetime.isoformat(), \"curve\": np.array([...]).tolist()})","handlingStrategy":"validation","validationCode":"ALLOWED = (str, int, float, bool, type(None), list, tuple, dict)\ndef check_flattenable(value, path=\"root\"):\n    if isinstance(value, ALLOWED):\n        return True\n    if hasattr(value, \"__dataclass_fields__\"):\n        return True\n    raise TypeError(f\"unflattenable {type(value).__name__} at {path}\")","typeGuard":"def is_flattenable(value) -> bool:\n    from dataclasses import is_dataclass\n    return isinstance(value, (str, int, float, bool, type(None), list, tuple, dict)) or is_dataclass(value)","tryCatchPattern":"try:\n    artifact = build_dcf_artifact(...)\nexcept TypeError as e:\n    if \"cannot normalize\" in str(e):\n        # sanitize inputs (isoformat datetimes, .tolist() arrays) and retry\n        ...\n    raise","preventionTips":["Convert datetimes to .isoformat() and numpy values to .item()/.tolist() before putting them in artifact inputs.","Keep artifact inputs to primitives plus dataclasses/Assumption."],"tags":["python","serialization","hashing","type-validation"],"backgroundTag":"unsupported-type-for-serialization","analyzedSha":"80ffdda44c5c4db0dd84d70e051cca591cea67df","analyzedAt":"2026-08-28T12:46:38.989Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}