{"record":{"id":"a2c3b16f99371389","repo":"babalae/better-genshin-impact","slug":"invalid-key-format-for-sctp","errorCode":null,"errorMessage":"Invalid key format for sctp.","messagePattern":"Invalid key format for sctp\\.","errorType":"validation","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"BetterGenshinImpact/Service/Notifier/ServerChanNotifier.cs","lineNumber":87,"sourceCode":"    }\n\n    /// <summary>\n    /// 根据sendKey格式获取正确的API URL\n    /// </summary>\n    private string GetServerChanApiUrl(string key)\n    {\n        // 判断sendkey是否以\"sctp\"开头并提取数字部分\n        if (key.StartsWith(\"sctp\"))\n        {\n            var match = Regex.Match(key, @\"^sctp(\\d+)t\");\n            if (match.Success)\n            {\n                var num = match.Groups[1].Value;\n                return $\"https://{num}.push.ft07.com/send/{key}.send\";\n            }\n            else\n            {\n                throw new ArgumentException(\"Invalid key format for sctp.\");\n            }\n        }\n        else\n        {\n            return $\"https://sctapi.ftqq.com/{key}.send\";\n        }\n    }\n\n    /// <summary>\n    /// 生成通知描述内容\n    /// </summary>\n    private string GenerateDescription(BaseNotificationData data)\n    {\n        var sb = new StringBuilder();\n\n        // 添加事件时间\n        sb.AppendLine($\"**时间**: {data.Timestamp.ToString(\"yyyy-MM-dd HH:mm:ss\")}\");\n","sourceCodeStart":69,"sourceCodeEnd":105,"githubUrl":"https://github.com/babalae/better-genshin-impact/blob/a7cb36712dcb409be610257d877fcea3597e9d6b/BetterGenshinImpact/Service/Notifier/ServerChanNotifier.cs#L69-L105","documentation":"ArgumentException thrown by GetServerChanApiUrl when the SendKey starts with \"sctp\" but does not match the regex ^sctp(\\d+)t (e.g. sctpABCDt, sctp123x). The sctp format is sctp{number}t{rest}; without the numeric segment the ft07 endpoint number cannot be derived. NOTE: because this is thrown inside SendAsync's try, it is normally swallowed and re-emerged as the generic error-530 message.","triggerScenarios":"key.StartsWith(\"sctp\") is true but Regex.Match(key, @\"^sctp(\\d+)t\") fails (no digits between sctp and t).","commonSituations":"User pasted a ServerChanTurbo 2024 key with a typo; trailing/leading characters; copied only part of the key; legacy non-numeric sctp variant the regex does not anticipate.","solutions":["Re-copy the full sctp key from the ft07 dashboard, ensuring it matches sctp{digits}t{token}.","Loosen or clarify the regex if the official format changed, and surface a clear message.","Move format validation to construction time so the user sees the specific error rather than the catch-all 530 wrapper."],"exampleFix":"// before\nif (key.StartsWith(\"sctp\"))\n{\n    var match = Regex.Match(key, @\"^sctp(\\d+)t\");\n    if (match.Success) { ... }\n    else throw new ArgumentException(\"Invalid key format for sctp.\");\n}\n\n// after — clearer message and validate before the network try-block\nvar match = Regex.Match(key, @\"^sctp(\\d+)t\");\nif (!match.Success)\n    throw new ArgumentException(\"sctp SendKey 必须形如 sctp<数字>t<token>，当前值不符合: \" + key);\nvar num = match.Groups[1].Value;\nreturn $\"https://{num}.push.ft07.com/send/{key}.send\";","handlingStrategy":"validation","validationCode":"if (sendKey.StartsWith(\"sctp\") && !Regex.IsMatch(sendKey, @\"^sctp\\d+t\"))\n    throw new InvalidOperationException($\"sctp SendKey must match sctp<digits>t<token>: '{sendKey}'\");","typeGuard":"static bool IsValidSctpKey(string key)\n    => !key.StartsWith(\"sctp\") || Regex.IsMatch(key, @\"^sctp\\d+t\");","tryCatchPattern":"try { string url = GetServerChanApiUrl(sendKey); }\ncatch (ArgumentException ex) when (ex.Message.Contains(\"sctp\"))\n{ /* prompt user to re-copy the ft07 SendKey, no retry */ }","preventionTips":["Validate the sctp key format at settings-save time, not just at send time.","Show the expected format (sctp<digits>t<token>) in the UI.","Re-copy the full key from the ft07 dashboard."],"tags":["serverchan","config","validation","regex","notifier"],"backgroundTag":null,"analyzedSha":"a7cb36712dcb409be610257d877fcea3597e9d6b","analyzedAt":"2026-08-13T16:44:57.548Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}