{"record":{"id":"174eb3561b5404d6","repo":"EllanJiang/GameFramework","slug":"data-table-is-invalid","errorCode":null,"errorMessage":"Data table is invalid.","messagePattern":"Data table is invalid\\.","errorType":"exception","errorClass":"GameFrameworkException","httpStatus":null,"severity":"error","filePath":"GameFramework/DataTable/DataTableManager.cs","lineNumber":459,"sourceCode":"            if (!typeof(IDataRow).IsAssignableFrom(dataRowType))\n            {\n                throw new GameFrameworkException(Utility.Text.Format(\"Data row type '{0}' is invalid.\", dataRowType.FullName));\n            }\n\n            return InternalDestroyDataTable(new TypeNamePair(dataRowType, name));\n        }\n\n        /// <summary>\n        /// 销毁数据表。\n        /// </summary>\n        /// <typeparam name=\"T\">数据表行的类型。</typeparam>\n        /// <param name=\"dataTable\">要销毁的数据表。</param>\n        /// <returns>是否销毁数据表成功。</returns>\n        public bool DestroyDataTable<T>(IDataTable<T> dataTable) where T : IDataRow\n        {\n            if (dataTable == null)\n            {\n                throw new GameFrameworkException(\"Data table is invalid.\");\n            }\n\n            return InternalDestroyDataTable(new TypeNamePair(typeof(T), dataTable.Name));\n        }\n\n        /// <summary>\n        /// 销毁数据表。\n        /// </summary>\n        /// <param name=\"dataTable\">要销毁的数据表。</param>\n        /// <returns>是否销毁数据表成功。</returns>\n        public bool DestroyDataTable(DataTableBase dataTable)\n        {\n            if (dataTable == null)\n            {\n                throw new GameFrameworkException(\"Data table is invalid.\");\n            }\n\n            return InternalDestroyDataTable(new TypeNamePair(dataTable.Type, dataTable.Name));","sourceCodeStart":441,"sourceCodeEnd":477,"githubUrl":"https://github.com/EllanJiang/GameFramework/blob/d0c010b05167c58e92350449d04864a91ca13fd2/GameFramework/DataTable/DataTableManager.cs#L441-L477","documentation":"DestroyDataTable<T>(IDataTable<T>) throws this when the dataTable argument is null. The manager cannot read the table's Name to build its lookup key, so it fails fast. This indicates the caller no longer holds a valid table reference.","triggerScenarios":"Calling DestroyDataTable(myTable) where myTable was already destroyed, never created, or an out/return value that was null; passing a cached table reference after table cleanup.","commonSituations":"Destroying tables on scene unload when a cached reference is stale; holding an IDataTable<T> from a manager that was already cleared; null-returning lookups passed straight to Destroy.","solutions":["Check the table reference for null before calling DestroyDataTable.","Re-acquire the table with HasDataTable/GetDataTable to confirm it exists before destroying.","Fix the code path that produced a null table reference (failed creation or prior destruction)."],"exampleFix":"// before\nm_DataTableManager.DestroyDataTable(m_EnemyTable);\n// after\nif (m_EnemyTable != null)\n{\n    m_DataTableManager.DestroyDataTable(m_EnemyTable);\n    m_EnemyTable = null;\n}","handlingStrategy":"type-guard","validationCode":"if (dataTable == null) return false; // or log and skip","typeGuard":"static bool IsValidTable<T>(IDataTable<T> t) where T : IDataRow => t != null && !string.IsNullOrEmpty(t.Name);","tryCatchPattern":"try { manager.DestroyDataTable(table); }\ncatch (GameFrameworkException) { Log.Warning(\"Attempted to destroy a null data table\"); }","preventionTips":["Null-out cached table references immediately after destroying","Check HasDataTable before operating on cached references","Avoid storing table references across scene loads"],"tags":["datatable","null-reference","csharp","gameframework"],"backgroundTag":"null-argument","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"}