{"record":{"id":"aa504d5d2632360c","repo":"egametang/ET","slug":"err-locationlockownermismatch","errorCode":"ERR_LocationLockOwnerMismatch","errorMessage":"location lock owner mismatch type: {locationType} key: {key} requestActorId: {actorId} holdActorId: {state.ActorId}","messagePattern":"location lock owner mismatch type: (.+?) key: (.+?) requestActorId: (.+?) holdActorId: (.+?)","errorType":"exception","errorClass":"RpcException","httpStatus":null,"severity":"error","filePath":"Packages/cn.etetet.actorlocation/Scripts/Hotfix/Server/LocationComponentSystem.cs","lineNumber":431,"sourceCode":"                    locationInfo.TypeStates[locationType] = state;\n                }\n\n                if (IsLocked(state))\n                {\n                    if (state.ActorId == actorId)\n                    {\n                        Log.Warning(\n                            $\"location lock idempotent type: {locationType} key: {key} actorId: {actorId} lockToken: {state.LockToken}\");\n                        return state.LockToken;\n                    }\n\n                    throw new RpcException(ErrorCode.ERR_LocationAlreadyLocked,\n                        $\"location lock already exists type: {locationType} key: {key} actorId: {state.ActorId} requestActorId: {actorId}\");\n                }\n\n                if (exists && state.ActorId != default && state.ActorId != actorId)\n                {\n                    throw new RpcException(ErrorCode.ERR_LocationLockOwnerMismatch,\n                        $\"location lock owner mismatch type: {locationType} key: {key} requestActorId: {actorId} holdActorId: {state.ActorId}\");\n                }\n\n                long lockToken = IdGenerater.Instance.GenerateId();\n                long lockExpireTime = time > 0 ? self.GetSingleton<TimeInfo>().ServerNow() + time : 0;\n                state.ActorId = actorId;\n                state.LockToken = lockToken;\n                state.LockExpireTime = lockExpireTime;\n                locationInfo.TypeStates[locationType] = state;\n\n                try\n                {\n                    await self.SaveInfoToDB(locationInfo);\n                }\n                catch\n                {\n                    self = selfRef;\n                    if (self != null)","sourceCodeStart":413,"sourceCodeEnd":449,"githubUrl":"https://github.com/egametang/ET/blob/5cab01f7a8bee5f49f4781eebe9e2b1c6d7ebe0f/Packages/cn.etetet.actorlocation/Scripts/Hotfix/Server/LocationComponentSystem.cs#L413-L449","documentation":"CreateBuff wraps its entire body in try/catch and re-throws a generic Exception carrying buffId, buffConfigId, casterId, with the real cause as InnerException. The visible message is a wrapper; the actual failure lives in e.InnerException — most often a missing BuffConfig, an AddChildWithId id collision, or a null config field (Flags/Effects/Duration).","triggerScenarios":"BuffConfig not resolvable for buffConfigId (buff.GetConfig() returns null/incomplete downstream); AddChildWithId<Buff,int>(buffId, buffConfigId) collides with an existing child id; a malformed config field (null Effects, bad Stack) throws during the flag/effect indexing loops.","commonSituations":"Buff config table (Luban export) missing the configId; spell/buff assets not re-exported after editing; duplicate buffId passed while a buff with that id is still alive; config Duration/TickTime fields invalid.","solutions":["Inspect ex.InnerException for the true root cause before acting on the wrapper message.","Verify a BuffConfig exists for buffConfigId in the exported config category before calling CreateBuff.","Ensure buffId is unique among live children of this BuffComponent (no reuse while a buff is alive).","Re-export spell/buff configs via Luban/ScriptableObject pipeline if config is stale or missing."],"exampleFix":"// before\nBuff buff = self.CreateBuff(buffId, buffConfigId, casterId);\n\n// after\nBuffConfig cfg = BuffConfigCategory.Instance.Get(buffConfigId);\nif (cfg == null)\n{\n    Log.Error($\"buff config missing: {buffConfigId}, cannot create buff {buffId}\");\n    return null;\n}\nBuff buff = self.CreateBuff(buffId, buffConfigId, casterId);","handlingStrategy":"validation","validationCode":"BuffConfig cfg = BuffConfigCategory.Instance.Get(buffConfigId);\nif (cfg == null)\n{\n    Log.Error($\"cannot create buff: config {buffConfigId} not found\");\n    return null;\n}","typeGuard":null,"tryCatchPattern":"try\n{\n    Buff buff = component.CreateBuff(buffId, buffConfigId, casterId);\n}\ncatch (Exception ex)\n{\n    Log.Error($\"create buff failed {buffId} {buffConfigId} {casterId}: {ex.InnerException?.Message ?? ex.Message}\");\n}","preventionTips":["Resolve BuffConfig and assert non-null before CreateBuff.","Guarantee buffId uniqueness among live buffs on the same BuffComponent.","Always log/read InnerException — the outer message is only a wrapper.","Re-export spell/buff configs after any config asset edit."],"tags":["spell","buff","config","luban","runtime"],"backgroundTag":null,"analyzedSha":"5cab01f7a8bee5f49f4781eebe9e2b1c6d7ebe0f","analyzedAt":"2026-08-13T21:10:40.377Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}