{"record":{"id":"686bed004e943598","repo":"EllanJiang/GameFramework","slug":"data-is-invalid","errorCode":null,"errorMessage":"Data is invalid.","messagePattern":"Data is invalid\\.","errorType":"exception","errorClass":"GameFrameworkException","httpStatus":null,"severity":"error","filePath":"GameFramework/Base/TaskPool/TaskInfo.cs","lineNumber":66,"sourceCode":"        /// </summary>\n        public bool IsValid\n        {\n            get\n            {\n                return m_IsValid;\n            }\n        }\n\n        /// <summary>\n        /// 获取任务的序列编号。\n        /// </summary>\n        public int SerialId\n        {\n            get\n            {\n                if (!m_IsValid)\n                {\n                    throw new GameFrameworkException(\"Data is invalid.\");\n                }\n\n                return m_SerialId;\n            }\n        }\n\n        /// <summary>\n        /// 获取任务的标签。\n        /// </summary>\n        public string Tag\n        {\n            get\n            {\n                if (!m_IsValid)\n                {\n                    throw new GameFrameworkException(\"Data is invalid.\");\n                }\n","sourceCodeStart":48,"sourceCodeEnd":84,"githubUrl":"https://github.com/EllanJiang/GameFramework/blob/d0c010b05167c58e92350449d04864a91ca13fd2/GameFramework/Base/TaskPool/TaskInfo.cs#L48-L84","documentation":"TaskInfo is a lightweight wrapper around task data in the TaskPool. Its properties (SerialId, etc.) throw 'Data is invalid.' when accessed while m_IsValid is false — i.e. after the task info has been reset/invalidated (for example when the task completed or was shut down and TaskInfo.Reset/invalidation ran). Accessing fields of a dead TaskInfo is a use-after-free-style bug in the task lifecycle.","triggerScenarios":"Reading SerialId (or other properties) on a TaskInfo whose m_IsValid is false — typically after TaskPool task completion/shutdown reset the TaskInfo, but a callback, closure, or cached reference still holds and reads it asynchronously.","commonSituations":"Async completion callbacks firing after the task pool was shut down or the task was cancelled and its TaskInfo reset; storing TaskInfo references longer than the task's lifetime and reading them later; starve/shutdown paths invalidating infos while workers still inspect them.","solutions":["Check the TaskInfo's valid state (IsValid / m_IsValid backing flag) before reading its properties.","Copy needed values (SerialId, etc.) into your own fields while the task is still valid, rather than reading the TaskInfo later.","Fix callback lifetimes: unsubscribe or guard callbacks so they do not run after the task info has been reset by shutdown or completion."],"exampleFix":"// before\nvoid OnDone(TaskInfo info) { Log(info.SerialId); } // may be invalid\n\n// after\nvoid OnDone(TaskInfo info)\n{\n    int serialId = info.SerialId; // read while valid, inside task execution\n    ... // or check IsValid / capture id at task start instead\n}","handlingStrategy":"try-catch","validationCode":"// guard reads on a possibly-invalid TaskInfo\nif (taskInfo.IsValid)\n{\n    int id = taskInfo.SerialId;\n}","typeGuard":"bool TryGetSerialId(TaskInfo info, out int serialId)\n{\n    serialId = 0;\n    try { serialId = info.SerialId; return true; }\n    catch (GameFrameworkException) { return false; }\n}","tryCatchPattern":"try\n{\n    int serialId = taskInfo.SerialId;\n}\ncatch (GameFrameworkException ex) when (ex.Message == \"Data is invalid.\")\n{\n    // TaskInfo was reset (completed/cancelled/shutdown) — abandon stale reads\n}","preventionTips":["Read TaskInfo properties only inside the task's execution window, not in later callbacks.","Capture SerialId into a local/own field when the task starts if you need it after completion.","Cancel or unsubscribe callbacks on TaskPool shutdown so they never touch invalidated TaskInfos."],"tags":["task-pool","invalid-state","lifecycle","use-after-free"],"backgroundTag":"invalid-state-transition","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"}