{"record":{"id":"535736b06c7a49d2","repo":"vectordotdev/vector","slug":"could-not-convert-duration-to-json","errorCode":null,"errorMessage":"Could not convert duration to JSON","messagePattern":"Could not convert duration to JSON","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"lib/vector-config/src/stdlib.rs","lineNumber":501,"sourceCode":"\n    fn generate_schema(_: &RefCell<SchemaGenerator>) -> Result<SchemaObject, GenerateError> {\n        let mut properties = IndexMap::default();\n        properties.insert(\"secs\".into(), generate_number_schema::<u64>());\n        properties.insert(\"nsecs\".into(), generate_number_schema::<u32>());\n\n        let mut required = BTreeSet::default();\n        required.insert(\"secs\".into());\n        required.insert(\"nsecs\".into());\n\n        Ok(crate::schema::generate_struct_schema(\n            properties, required, None,\n        ))\n    }\n}\n\nimpl ToValue for Duration {\n    fn to_value(&self) -> Value {\n        serde_json::to_value(self).expect(\"Could not convert duration to JSON\")\n    }\n}\n","sourceCodeStart":483,"sourceCodeEnd":504,"githubUrl":"https://github.com/vectordotdev/vector/blob/bdb87aeaa4c4ff27c0ba643c1c77b21bf2ef4013/lib/vector-config/src/stdlib.rs#L483-L504","documentation":"ToValue for std::time::Duration serializes the duration with serde_json::to_value and expects success. serde_json::to_value can only fail for non-string-keyed maps or unsupported types, so this panic indicates a serde_json serialization invariant was violated while converting a Duration to a config Value.","triggerScenarios":"Calling to_value() on a config struct containing a Duration field where serde_json serialization unexpectedly fails (e.g. a custom Serialize impl returning an error, or serialization of a map with non-string keys nested in the duration wrapper).","commonSituations":"Building config schemas or merging default configs that include Duration fields; rare in practice because Duration serializes deterministically — usually seen when someone adds a custom Serializer/Serializer impl around Duration.","solutions":["Check for a custom Serialize implementation for Duration (or a wrapper type) that can fail; make it infallible.","Ensure no serde_json serializer feature flags (e.g. arbitrary_precision mismatches) differ between build units.","Verify no manual ToValue impl produces a non-JSON-serializable intermediate value.","Update serde_json/vector-config to a matching version so Duration serialization behaves as expected."],"exampleFix":"// before\nimpl Serialize for MyDurationWrapper {\n    fn serialize<S>(&self, s: S) -> Result<S::Ok, S::Error> { Err(serde::ser::Error::custom(\"unsupported\")) }\n}\n// after\nimpl Serialize for MyDurationWrapper {\n    fn serialize<S>(&self, s: S) -> Result<S::Ok, S::Error> { self.as_secs_f64().serialize(s) }\n}","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"fn duration_to_value(d: &Duration) -> Option<Value> {\n    serde_json::to_value(d).ok()\n}","tryCatchPattern":"// Rust has no catch; avoid expect by handling Result\nlet value = serde_json::to_value(duration).unwrap_or_else(|e| {\n    eprintln!(\"duration serialization failed: {e}\");\n    Value::Null\n});","preventionTips":["Do not implement fallible custom Serialize impls for Duration wrappers.","Keep serde/serde_json versions aligned across workspace crates.","Prefer storing durations as u64 millis/secs in config structures."],"tags":["json","duration","serialization","panic"],"backgroundTag":"json-marshal-failed","analyzedSha":"bdb87aeaa4c4ff27c0ba643c1c77b21bf2ef4013","analyzedAt":"2026-09-16T02:53:35.741Z","contentChangedAt":"2026-09-16T02:53:35.741Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}