{"record":{"id":"3f39fa164ac7abb6","repo":"linera-io/linera-protocol","slug":"invalid-stream-id-s","errorCode":null,"errorMessage":"Invalid stream ID: {s}","messagePattern":"Invalid stream ID: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"linera-base/src/identifiers.rs","lineNumber":707,"sourceCode":"        Display::fmt(&self.stream_name, f)\n    }\n}\n\nimpl std::str::FromStr for StreamId {\n    type Err = anyhow::Error;\n\n    fn from_str(s: &str) -> Result<Self, Self::Err> {\n        let parts = s.rsplit_once(\":\");\n        if let Some((part0, part1)) = parts {\n            let application_id =\n                GenericApplicationId::from_str(part0).context(\"Invalid GenericApplicationId!\")?;\n            let stream_name = StreamName::from_str(part1).context(\"Invalid StreamName!\")?;\n            Ok(StreamId {\n                application_id,\n                stream_name,\n            })\n        } else {\n            Err(anyhow!(\"Invalid stream ID: {s}\"))\n        }\n    }\n}\n\n/// An event identifier.\n#[derive(\n    Debug,\n    PartialEq,\n    Eq,\n    Hash,\n    Clone,\n    Serialize,\n    Deserialize,\n    WitLoad,\n    WitStore,\n    WitType,\n    SimpleObject,\n    Allocative,","sourceCodeStart":689,"sourceCodeEnd":725,"githubUrl":"https://github.com/linera-io/linera-protocol/blob/6c226ddcb332ef55118dc8d0aafbd093d5420899/linera-base/src/identifiers.rs#L689-L725","documentation":"StreamId::from_str splits the string on the LAST colon (rsplit_once): the left part must parse as a GenericApplicationId ('System' or 'User:<id>'), the right part as a StreamName (hex bytes). If there is no colon at all, this error is raised; a colon present but malformed parts surfaces the chained 'Invalid GenericApplicationId!'/'Invalid StreamName!' errors instead.","triggerScenarios":"Calling parse::<StreamId>() on a string with no ':' at all, e.g. a bare stream name like 'a1b2c3' or an application ID alone. Valid shapes are 'System:a1b2' and 'User:e40c...:a1b2'.","commonSituations":"Config or query parameters that carry only the stream name; copying the StreamName component instead of the full StreamId; truncation when the hex stream name is dropped.","solutions":["Use the full Display form '<application-id>:<stream-name-hex>', e.g. 'User:e40c...:a1b2'","Stream names are hex-encoded bytes (StreamName::from_str uses hex::decode), so keep them valid hex","Round-trip through StreamId::to_string() rather than manual formatting"],"exampleFix":"// before: bare stream name, no colon\nlet id: StreamId = stream_name_hex.parse()?; // Err: Invalid stream ID\n\n// after: application id + ':' + hex stream name\nlet id: StreamId = format!(\"System:{stream_name_hex}\").parse()?;","handlingStrategy":"type-guard","validationCode":"fn looks_like_stream_id(s: &str) -> bool {\n    let Some((app, name)) = s.rsplit_once(':') else { return false };\n    (app == \"System\" || app.starts_with(\"User:\"))\n        && !name.is_empty()\n        && name.bytes().all(|b| b.is_ascii_hexdigit())\n}","typeGuard":"fn parse_stream_id(s: &str) -> Option<StreamId> {\n    s.parse().ok()\n}","tryCatchPattern":null,"preventionTips":["Require the full '<application-id>:<hex-stream-name>' form in configs and APIs","Stream names are hex; reject non-hex early at input boundaries","Round-trip through StreamId::to_string() instead of manual formatting"],"tags":["parsing","identifier","stream-id","linera-base","rust"],"backgroundTag":"invalid-identifier-format","analyzedSha":"6c226ddcb332ef55118dc8d0aafbd093d5420899","analyzedAt":"2026-08-22T22:49:09.787Z","schemaVersion":2},"datasetVersion":"2026-08-23T01:17:44.959Z"}