{"record":{"id":"0bf426a2d3933978","repo":"Tyrrrz/DiscordChatExporter","slug":"invalid-snowflake-value","errorCode":null,"errorMessage":"Invalid snowflake '{value}'.","messagePattern":"Invalid snowflake '(.+?)'\\.","errorType":"validation","errorClass":"FormatException","httpStatus":null,"severity":"error","filePath":"DiscordChatExporter.Core/Discord/Snowflake.cs","lineNumber":43,"sourceCode":"    public static Snowflake? TryParse(string? value, IFormatProvider? formatProvider = null)\n    {\n        if (string.IsNullOrWhiteSpace(value))\n            return null;\n\n        // As number\n        if (ulong.TryParse(value, NumberStyles.None, formatProvider, out var number))\n            return new Snowflake(number);\n\n        // As date\n        if (DateTimeOffset.TryParse(value, formatProvider, DateTimeStyles.None, out var instant))\n            return FromDate(instant);\n\n        return null;\n    }\n\n    public static Snowflake Parse(string value, IFormatProvider? formatProvider) =>\n        TryParse(value, formatProvider)\n        ?? throw new FormatException($\"Invalid snowflake '{value}'.\");\n\n    public static Snowflake Parse(string value) => Parse(value, null);\n}\n\npublic partial record struct Snowflake : IComparable<Snowflake>, IComparable\n{\n    public int CompareTo(Snowflake other) => Value.CompareTo(other.Value);\n\n    public int CompareTo(object? obj)\n    {\n        if (obj is not Snowflake other)\n            throw new ArgumentException($\"Object must be of type {nameof(Snowflake)}.\");\n\n        return Value.CompareTo(other.Value);\n    }\n\n    public static bool operator >(Snowflake left, Snowflake right) => left.CompareTo(right) > 0;\n","sourceCodeStart":25,"sourceCodeEnd":61,"githubUrl":"https://github.com/Tyrrrz/DiscordChatExporter/blob/f6865c82167c3bfee4455da80a1f1ca5e71b95ad/DiscordChatExporter.Core/Discord/Snowflake.cs#L25-L61","documentation":"Thrown as FormatException by Snowflake.Parse when TryParse cannot interpret the input as either an unsigned 64-bit integer or a parseable DateTimeOffset. Snowflakes are Discord's numeric IDs but the parser also accepts ISO/date strings for convenience; anything else is invalid. This is a parsing error typically surfaced by CLI argument binding.","triggerScenarios":"Snowflake.Parse is called (e.g. when binding a -c/--channel, -g/--guild, or date argument) with a value that is neither a plain numeric string nor a culture-parseable date. TryParse returns null at Snowflake.cs:36 and Parse throws.","commonSituations":"Pasting a channel URL fragment instead of the bare ID (e.g. '/channels/123/456'); ID with commas/thousands separators; locale-specific date string that does not parse with the configured culture; leading '<#' or trailing '>' from a copied mention; negative or decimal number.","solutions":["Supply the raw numeric snowflake (e.g. `1234567890123456789`) with no formatting.","For date inputs, use an unambiguous ISO-8601 string (e.g. `2024-01-31T00:00:00Z`).","Strip mention markup (`<#`, `<@`, `>`) and URL fragments before parsing.","If parsing with a specific culture, pass an IFormatProvider whose date formats accept your string."],"exampleFix":"// before\nvar id = Snowflake.Parse(\"<#1234567890123456789>\");\n// after\nvar id = Snowflake.Parse(\"1234567890123456789\");","handlingStrategy":"type-guard","validationCode":"bool IsLikelySnowflake(string s) =>\n    ulong.TryParse(s, NumberStyles.None, CultureInfo.InvariantCulture, out _);\nif (!IsLikelySnowflake(input)) throw new ArgumentException($\"'{input}' is not a numeric snowflake.\");","typeGuard":"static Snowflake? TryParseSnowflake(string? raw) =>\n    string.IsNullOrWhiteSpace(raw) ? null : Snowflake.TryParse(raw, CultureInfo.InvariantCulture);","tryCatchPattern":"try { var id = Snowflake.Parse(raw, CultureInfo.InvariantCulture); }\ncatch (FormatException) { logger.LogWarning(\"Ignoring malformed id '{Raw}'\", raw); return; }","preventionTips":["Strip mention markup and URL fragments before parsing.","Use NumberStyles.None and InvariantCulture for numeric IDs.","Validate inputs at the CLI boundary with a type guard before queueing."],"tags":["parsing","snowflake","identifiers","cli"],"backgroundTag":null,"analyzedSha":"f6865c82167c3bfee4455da80a1f1ca5e71b95ad","analyzedAt":"2026-08-13T18:08:46.403Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}