{"record":{"id":"e3a8a6c0bf5cca57","repo":"netchx/netch","slug":"specified-server-type-is-not-supported","errorCode":null,"errorMessage":"Specified server type is not supported.","messagePattern":"Specified server type is not supported\\.","errorType":"exception","errorClass":"NotSupportedException","httpStatus":null,"severity":"error","filePath":"Netch/Utils/ServerHelper.cs","lineNumber":21,"sourceCode":"\nnamespace Netch.Utils;\n\npublic static class ServerHelper\n{\n    static ServerHelper()\n    {\n        var serversUtilsTypes = Assembly.GetExecutingAssembly()\n            .GetExportedTypes()\n            .Where(type => type.GetInterfaces().Contains(typeof(IServerUtil)));\n\n        ServerUtilDictionary = serversUtilsTypes.Select(t => (IServerUtil)Activator.CreateInstance(t)!).ToDictionary(util => util.TypeName);\n    }\n\n    public static Dictionary<string, IServerUtil> ServerUtilDictionary { get; }\n\n    public static IServerUtil GetUtilByTypeName(string typeName)\n    {\n        return ServerUtilDictionary.GetValueOrDefault(typeName) ?? throw new NotSupportedException(\"Specified server type is not supported.\");\n    }\n\n    public static IServerUtil? GetUtilByUriScheme(string scheme)\n    {\n        return ServerUtilDictionary.Values.SingleOrDefault(i => i.UriScheme.Any(s => s.Equals(scheme)));\n    }\n\n    public static Type GetTypeByTypeName(string typeName)\n    {\n        return GetUtilByTypeName(typeName).ServerType;\n    }\n}","sourceCodeStart":3,"sourceCodeEnd":33,"githubUrl":"https://github.com/netchx/netch/blob/9d99eb1c5a2acbf2a34f2600f94242601019a300/Netch/Utils/ServerHelper.cs#L3-L33","documentation":"ServerHelper builds ServerUtilDictionary once, via reflection over every exported type in the executing assembly that implements IServerUtil, keyed by each util's TypeName. GetUtilByTypeName returns the util for a TypeName or throws NotSupportedException if it is not registered. So the error means a Server.Type value has no matching IServerUtil implementation loaded in this assembly - typically a protocol this Netch build does not ship support for, or a corrupted/imported Type field. Note Server.ToString() also calls GetUtilByTypeName, so even rendering a bad server in a list can trigger it.","triggerScenarios":"Deserializing a settings.json whose server has a Type with no matching IServerUtil; loading a config from a Netch version that removed a server type present in this one; a Server.ToString() call (UI binding) on such a server; the reflection dictionary built before the util assembly was loaded.","commonSituations":"Downgrading Netch across a release that removed a server type; importing a share link whose scheme maps to an unimplemented type; a custom server plugin not present in this build; a hand-edited Type field in settings.json.","solutions":["Update Netch to a version that supports the server's Type.","Remove the unsupported server entries from settings.json / the server list.","Re-import the server using a supported protocol.","If developing a custom protocol, ensure its IServerUtil implementation is compiled into the executing assembly so reflection picks it up."],"exampleFix":"// before\nreturn ServerUtilDictionary.GetValueOrDefault(typeName) ?? throw new NotSupportedException(\"Specified server type is not supported.\");\n// after - return null and let callers skip unknown servers gracefully\nreturn ServerUtilDictionary.GetValueOrDefault(typeName);","handlingStrategy":"validation","validationCode":"if (!ServerHelper.ServerUtilDictionary.ContainsKey(server.Type))\n{\n    Log.Warning(\"Skipping server '{Remark}': unknown type '{Type}'\", server.Remark, server.Type);\n    continue; // or remove the entry\n}\nvar util = ServerHelper.GetUtilByTypeName(server.Type);","typeGuard":"bool IsSupportedServerType(string typeName) => ServerHelper.ServerUtilDictionary.ContainsKey(typeName);","tryCatchPattern":"try { var util = ServerHelper.GetUtilByTypeName(typeName); }\ncatch (NotSupportedException)\n{\n    Log.Warning(\"Unsupported server type '{Type}' skipped\", typeName);\n    continue;\n}","preventionTips":["On config load, filter out servers whose Type is not in ServerUtilDictionary and log them.","Guard Server.ToString() against missing utils so a single bad server does not crash UI rendering.","When removing a protocol in a release, migrate or prune affected entries from existing configs.","Add a startup assertion logging how many IServerUtil types were registered, to catch empty registration from a failed assembly load."],"tags":["server","reflection","config","registration","plugin"],"backgroundTag":null,"analyzedSha":"9d99eb1c5a2acbf2a34f2600f94242601019a300","analyzedAt":"2026-08-13T14:12:19.105Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}