{"record":{"id":"5fbb5030192628c6","repo":"nautechsystems/nautilus_trader","slug":"chart-function-must-be-callable-was-type-f","errorCode":null,"errorMessage":"Chart function must be callable, was {type(f)}","messagePattern":"Chart function must be callable, was (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/nautilus_trader/analysis/tearsheet.py","lineNumber":303,"sourceCode":"    ... def create_custom_chart(returns: pd.Series, **kwargs) -> go.Figure:\n    ...     fig = go.Figure()\n    ...     # ... custom visualization logic\n    ...     return fig\n    >>>\n    >>> # Or called directly\n    >>> register_chart(\"another_chart\", create_custom_chart)\n\n    \"\"\"\n    _require_not_none(name, \"name\")\n\n    if not name.strip():\n        raise ValueError(\"Chart name cannot be empty\")\n\n    if func is None:\n\n        def decorator(f: Callable) -> Callable:\n            if not callable(f):\n                raise ValueError(f\"Chart function must be callable, was {type(f)}\")\n            _CHART_REGISTRY[name] = f\n            return f\n\n        return decorator\n\n    if not callable(func):\n        raise ValueError(f\"Chart function must be callable, was {type(func)}\")\n\n    _CHART_REGISTRY[name] = func\n    return None\n\n\ndef get_chart(name: str) -> Callable:\n    \"\"\"\n    Get registered chart function by name.\n\n    Parameters\n    ----------","sourceCodeStart":285,"sourceCodeEnd":321,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/python/nautilus_trader/analysis/tearsheet.py#L285-L321","documentation":"Thrown via `anyhow::ensure!` when a contract's `proxy.kind` string is not one of the supported values `\"eip1967_implementation\"` or `\"zeppelinos_implementation\"`. The library only knows how to resolve implementation addresses for these two proxy standards.","triggerScenarios":"Manifest validation (verification.rs:1284) parses a contract that has a `proxy` object whose `kind` field is any other string — e.g. \"beacon\", \"transparent\", \"uups\", \"eip1967_admin\", a typo, or different casing.","commonSituations":"Using a beacon proxy or non-standard proxy pattern not covered by the two supported kinds; typos like \"eip1967-implementation\"; casing differences (\"EIP1967_Implementation\"); writing a custom proxy kind the verifier does not implement.","solutions":["Change `proxy.kind` to exactly \"eip1967_implementation\" or \"zeppelinos_implementation\".","If the proxy uses another pattern (e.g. beacon proxy), pin the implementation explicitly in the manifest in a supported way or extend the verifier to support that kind.","Check casing and separators — the comparison is an exact string match."],"exampleFix":"// before (manifest.json)\n\"proxy\": {\"kind\": \"beacon\"}\n// after (manifest.json)\n\"proxy\": {\"kind\": \"eip1967_implementation\"}","handlingStrategy":"validation","validationCode":"const KINDS: [&str; 2] = [\"eip1967_implementation\", \"zeppelinos_implementation\"]; if let Some(p) = &contract.proxy { assert!(KINDS.contains(&p.kind.as_str())); }","typeGuard":null,"tryCatchPattern":"match proxy.kind.as_str() { \"eip1967_implementation\" | \"zeppelinos_implementation\" => ok, other => bail!(\"unsupported proxy kind: {other}\") }","preventionTips":["Use an enum with serde for proxy.kind instead of free-form strings","Copy supported kind literals from the verifier source, exact case included","Test manifest parsing in CI to catch unsupported kinds early"],"tags":["validation","manifest","proxy","unsupported-value"],"backgroundTag":"unsupported-enum-value","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}