{"record":{"id":"29c3dba42dbb81fe","repo":"EllanJiang/GameFramework","slug":"resource-extension-is-invalid","errorCode":null,"errorMessage":"Resource extension is invalid.","messagePattern":"Resource extension is invalid\\.","errorType":"validation","errorClass":"GameFrameworkException","httpStatus":null,"severity":"error","filePath":"GameFramework/Resource/ResourceManager.ResourceName.cs","lineNumber":43,"sourceCode":"            private readonly string m_Variant;\n            private readonly string m_Extension;\n\n            /// <summary>\n            /// 初始化资源名称的新实例。\n            /// </summary>\n            /// <param name=\"name\">资源名称。</param>\n            /// <param name=\"variant\">变体名称。</param>\n            /// <param name=\"extension\">扩展名称。</param>\n            public ResourceName(string name, string variant, string extension)\n            {\n                if (string.IsNullOrEmpty(name))\n                {\n                    throw new GameFrameworkException(\"Resource name is invalid.\");\n                }\n\n                if (string.IsNullOrEmpty(extension))\n                {\n                    throw new GameFrameworkException(\"Resource extension is invalid.\");\n                }\n\n                m_Name = name;\n                m_Variant = variant;\n                m_Extension = extension;\n            }\n\n            /// <summary>\n            /// 获取资源名称。\n            /// </summary>\n            public string Name\n            {\n                get\n                {\n                    return m_Name;\n                }\n            }\n","sourceCodeStart":25,"sourceCodeEnd":61,"githubUrl":"https://github.com/EllanJiang/GameFramework/blob/d0c010b05167c58e92350449d04864a91ca13fd2/GameFramework/Resource/ResourceManager.ResourceName.cs#L25-L61","documentation":"The ResourceName constructor throws this when the `extension` argument is null or empty. Every resource name must carry a non-empty extension (e.g. \".dat\") so the ResourceManager can resolve the underlying file; the `variant` parameter is allowed to be empty but extension is not.","triggerScenarios":"Calling `new ResourceName(name, variant, null)` or `new ResourceName(name, variant, \"\")`, or passing a path whose extension was stripped/never captured by parsing code.","commonSituations":"Path parsing with Path.GetFileNameWithoutExtension losing the extension; version list data missing the extension field; hard-coded resource constructions that forgot the extension argument.","solutions":["Pass a non-empty extension string (e.g. \".dat\") when constructing ResourceName","Fix the parsing code that strips the extension from the source path","Verify version list / config data actually contains the extension for each resource"],"exampleFix":"// before\nvar name = new ResourceName(\"MyResource\", variant, Path.GetFileNameWithoutExtension(path));\n// after\nvar name = new ResourceName(\"MyResource\", variant, Path.GetExtension(path));","handlingStrategy":"validation","validationCode":"if (string.IsNullOrEmpty(extension)) throw new ArgumentException(\"Resource extension must be non-empty\", nameof(extension));","typeGuard":"bool IsValidResourceExtension(string ext) => !string.IsNullOrEmpty(ext);","tryCatchPattern":"try { var rn = new ResourceName(name, variant, ext); } catch (GameFrameworkException ex) { Log.Error($\"Invalid resource extension '{ext}': {ex.Message}\"); }","preventionTips":["Keep the extension in your resource path data end-to-end","Use Path.GetExtension rather than stripping extensions from parsed paths","Assert extension presence in version-list/config loading code"],"tags":["csharp","gameframework","resource","argument-validation"],"backgroundTag":"empty-required-field","analyzedSha":"d0c010b05167c58e92350449d04864a91ca13fd2","analyzedAt":"2026-09-15T13:37:15.352Z","contentChangedAt":"2026-09-15T13:37:15.352Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}