{"record":{"id":"03b9a29223f3c63a","repo":"nautechsystems/nautilus_trader","slug":"plotly-is-required-for-visualization-install-it-w","errorCode":null,"errorMessage":"plotly is required for visualization. Install it with: pip install nautilus_trader[visualization]","messagePattern":"plotly is required for visualization\\. Install it with: pip install nautilus_trader\\[visualization\\]","errorType":"exception","errorClass":"ImportError","httpStatus":null,"severity":"error","filePath":"python/nautilus_trader/analysis/tearsheet.py","lineNumber":424,"sourceCode":"        The run configuration ID. Defaults to ``engine.run_config_id``.\n\n    Returns\n    -------\n    str or None\n        HTML string if output_path is None, otherwise None.\n\n    Raises\n    ------\n    ImportError\n        If plotly is not installed.\n    ValueError\n        If ``bars_with_fills`` is configured without a node, a supplied node has no\n        run configuration ID, or the matching run configuration sets\n        ``dispose_on_completion=True``.\n\n    \"\"\"\n    if not PLOTLY_AVAILABLE:\n        raise ImportError(\n            \"plotly is required for visualization. \"\n            \"Install it with: pip install nautilus_trader[visualization]\",\n        )\n\n    _require_not_none(engine, \"engine\")\n\n    if not hasattr(engine, \"get_result\"):\n        return _create_tearsheet_from_result(\n            result=engine,\n            node=node,\n            run_config_id=run_config_id,\n            currency=currency,\n            output_path=output_path,\n            title=title,\n            config=config,\n            benchmark_returns=benchmark_returns,\n            benchmark_name=benchmark_name,\n        )","sourceCodeStart":406,"sourceCodeEnd":442,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/python/nautilus_trader/analysis/tearsheet.py#L406-L442","documentation":"Thrown when the proxy entry's `target_address` fails `Address::from_str`, i.e. it is not a valid 20-byte hex Ethereum address. This is the implementation contract address the proxy is expected to point at.","triggerScenarios":"Manifest validation (verification.rs:1296) parses a proxy whose `target_address` is malformed — wrong length, non-hex characters, empty string, or a non-address value pasted into the field.","commonSituations":"Truncated or mistyped implementation address; pasting an ENS name or checksummed-with-typo address; leaving the field as a placeholder when the proxy entry was added manually; confusing target_address with the proxy's own address.","solutions":["Correct `target_address` to the proxy's actual implementation address (0x + 40 hex chars).","Read the live implementation via eth_getStorageAt on the proxy slot and use that address.","Ensure you are not accidentally putting the proxy's own address in target_address."],"exampleFix":"// before (manifest.json)\n\"target_address\": \"implementation_contract\"\n// after (manifest.json)\n\"target_address\": \"0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\"","handlingStrategy":"validation","validationCode":"fn valid_eth_address(s: &str) -> bool { use alloy_primitives::Address; s.len() == 42 && Address::from_str(s).is_ok() } // apply to proxy.target_address","typeGuard":"fn parse_target(s: &str) -> Option<Address> { use alloy_primitives::Address; Address::from_str(s).ok() }","tryCatchPattern":"let target = Address::from_str(&proxy.target_address).map_err(|_| anyhow!(\"invalid proxy target_address\"))?;","preventionTips":["Resolve the implementation address on-chain before writing it into the manifest","Do not confuse the proxy address with the target (implementation) address","Reject ENS names and non-hex strings at manifest-authoring time"],"tags":["validation","manifest","proxy","hex-parsing"],"backgroundTag":"invalid-argument-format","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"}