{"record":{"id":"08927868b7b34930","repo":"nautechsystems/nautilus_trader","slug":"invalid-unixnanos-for-end","errorCode":null,"errorMessage":"Invalid `UnixNanos` for 'end'","messagePattern":"Invalid `UnixNanos` for 'end'","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/model/src/data/mod.rs","lineNumber":939,"sourceCode":"    /// - The `start` value contained in the metadata is invalid.\n    #[must_use]\n    pub fn start(&self) -> Option<UnixNanos> {\n        let metadata = self.metadata.as_ref()?;\n        let start_str = metadata.get_str(\"start\")?;\n        Some(UnixNanos::from_str(start_str).expect(\"Invalid `UnixNanos` for 'start'\"))\n    }\n\n    /// Returns an [`Option<UnixNanos>`] parsed from the metadata `end` field.\n    ///\n    /// # Panics\n    ///\n    /// This function panics if:\n    /// - The `end` value contained in the metadata is invalid.\n    #[must_use]\n    pub fn end(&self) -> Option<UnixNanos> {\n        let metadata = self.metadata.as_ref()?;\n        let end_str = metadata.get_str(\"end\")?;\n        Some(UnixNanos::from_str(end_str).expect(\"Invalid `UnixNanos` for 'end'\"))\n    }\n\n    /// Returns an [`Option<usize>`] parsed from the metadata `limit` field.\n    ///\n    /// # Panics\n    ///\n    /// This function panics if:\n    /// - The `limit` value contained in the metadata is invalid.\n    #[must_use]\n    pub fn limit(&self) -> Option<usize> {\n        let metadata = self.metadata.as_ref()?;\n        metadata.get_usize(\"limit\").or_else(|| {\n            metadata\n                .get_str(\"limit\")\n                .map(|s| s.parse::<usize>().expect(\"Invalid `usize` for 'limit'\"))\n        })\n    }\n}","sourceCodeStart":921,"sourceCodeEnd":957,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/model/src/data/mod.rs#L921-L957","documentation":"`Data::end` reads the metadata \"end\" key and parses it as `UnixNanos`, panicking with \"Invalid `UnixNanos` for 'end'\" if the string cannot be parsed. Absence of the key returns None; only a present-but-invalid value panics. It mirrors the `start` accessor and enforces canonical epoch-nanosecond metadata.","triggerScenarios":"Setting metadata[\"end\"] to a non-numeric string (ISO timestamp, float with decimals, empty string, ms-instead-of-ns epoch) and then calling `.end()` on the Data object.","commonSituations":"Custom data adapters writing human-readable end dates; config templates with placeholder values; mixed ms/ns timestamps across data sources.","solutions":["Write end as a Unix-nanosecond string, e.g. metadata[\"end\"] = str(int(dt.timestamp() * 1e9))","Use the library's timestamp conversion helpers instead of hand-formatted strings","Validate metadata before constructing the Data payload"],"exampleFix":"// before\nmetadata[\"end\"] = \"1704067200\"  // seconds, not nanoseconds — parses as valid but wrong? no: valid int, but if \"1.7040672e9\" it panics\n// after\nmetadata[\"end\"] = \"1704067200000000000\"  // Unix nanoseconds as integer string","handlingStrategy":"validation","validationCode":"def validate_end_metadata(metadata: dict) -> None:\n    raw = metadata.get(\"end\")\n    if raw is not None:\n        int(raw)  # raises ValueError if not a valid integer string\n        if int(raw) < 0:\n            raise ValueError(\"end must be a non-negative Unix-nanosecond value\")","typeGuard":"def is_unix_nanos_str(s: str) -> bool:\n    try:\n        return int(s) >= 0\n    except (ValueError, TypeError):\n        return False","tryCatchPattern":"try:\n    end = data.end()\nexcept Exception as e:\n    logger.error(f\"malformed 'end' metadata: {metadata.get('end')!r}\")\n    raise","preventionTips":["Write end as a Unix-nanosecond integer string","Use library timestamp converters instead of hand formatting","Validate metadata payloads before constructing Data objects"],"tags":["rust","panic","timestamp","metadata","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-14T05:17:10.506Z"}