{"record":{"id":"4a5b7dca15f88c59","repo":"moeru-ai/airi","slug":"player-not-found-stopped-following","errorCode":null,"errorMessage":"Player not found, stopped following","messagePattern":"Player not found, stopped following","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"integrations/minecraft/src/plugins/follow.ts","lineNumber":37,"sourceCode":"        state.following = username\n        logger.withFields({ username }).log('Starting to follow player')\n        followPlayer()\n      }\n\n      function stopFollow(): void {\n        state.following = undefined\n        logger.log('Stopping follow')\n        bot.bot.pathfinder.stop()\n      }\n\n      function followPlayer(): void {\n        if (!state.following)\n          return\n\n        const target = bot.bot.players[state.following]?.entity\n        if (!target) {\n          state.following = undefined\n          throw new Error('Player not found, stopped following')\n        }\n\n        const { x: playerX, y: playerY, z: playerZ } = target.position\n\n        bot.bot.pathfinder.setMovements(state.movements)\n        bot.bot.pathfinder.setGoal(new goals.GoalNear(playerX, playerY, playerZ, options?.rangeGoal ?? 1))\n      }\n\n      bot.onCommand('follow', (ctx) => {\n        const username = ctx.command!.sender\n        if (!username) {\n          throw new Error('Please specify a player name!')\n        }\n\n        startFollow(username)\n      })\n\n      bot.onCommand('stop', () => {","sourceCodeStart":19,"sourceCodeEnd":55,"githubUrl":"https://github.com/moeru-ai/airi/blob/27111382b4a79a7e983289d6e983a06af185ed0f/integrations/minecraft/src/plugins/follow.ts#L19-L55","documentation":"Thrown inside followPlayer() in the FollowCommand plugin. On each tick where state.following is set, it reads bot.bot.players[username]?.entity. If the followed player's entity is gone (player logged off, moved out of render distance, or despawned), it clears state.following and throws. The throw propagates out of the tick handler, so the follow silently stops (state cleared) and the error surfaces in the tick error path.","triggerScenarios":"The followed player disconnects from the server; the player moves beyond the server's entity tracking radius so bot.players[name].entity becomes undefined; the player enters a different dimension; the player is far enough that the server stops sending entity data.","commonSituations":"Long follow sessions where the target logs out; target teleporting across dimensions; target using /vanish or similar; high-latency connection dropping entity updates.","solutions":["Wrap the follow command call (or the tick handler) in try/catch to report 'lost player' gracefully instead of an uncaught throw.","Re-issue 'follow <name>' once the player is back in range.","Check bot.players[name]?.entity existence before starting follow.","Consider periodic re-validation and a cooldown before clearing the target."],"exampleFix":"// before\n//   function followPlayer(): void {\n//     const target = bot.bot.players[state.following]?.entity\n//     if (!target) {\n//       state.following = undefined\n//       throw new Error('Player not found, stopped following')\n//     }\n//     ...\n//   }\n//\n// after\n//   function followPlayer(): void {\n//     const target = bot.bot.players[state.following]?.entity\n//     if (!target) {\n//       state.following = undefined\n//       logger.log(`Stopped following: target no longer visible`)\n//       return\n//     }\n//     ...\n//   }","handlingStrategy":"try-catch","validationCode":"// Guard the follow target before relying on it each tick:\n// const target = bot.bot.players[state.following]?.entity\n// if (!target) { state.following = undefined; logger.log('follow target lost'); return }","typeGuard":"function hasEntity(p: unknown): p is { entity: object } {\n  return !!p && typeof p === 'object' && !!(p as any).entity\n}","tryCatchPattern":"// Wrap the follow tick so a lost target does not crash the tick loop:\n// try { followPlayer() }\n// catch (e) { logger.log('follow error:', errorMessageFrom(e)) }","preventionTips":["Validate bot.players[name]?.entity before starting follow.","Handle target logout/dimension-change gracefully (log instead of throw).","Re-issue 'follow <name>' once the player re-enters range.","Add a cooldown before clearing a transiently-lost target."],"tags":["minecraft","follow-plugin","player-entity","tick-handler"],"backgroundTag":null,"analyzedSha":"27111382b4a79a7e983289d6e983a06af185ed0f","analyzedAt":"2026-08-12T18:33:34.132Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}