{"record":{"id":"7abd33defd2df217","repo":"BabylonJS/Babylon.js","slug":"there-is-no-navmesh-generated","errorCode":null,"errorMessage":"There is no NavMesh generated.","messagePattern":"There is no NavMesh generated\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/dev/addons/src/navigation/plugin/RecastJSCrowd.ts","lineNumber":112,"sourceCode":"        /**\n         * The destination that the agent reached\n         */\n        destination: Vector3;\n    }>();\n\n    /**\n     * Constructor\n     * @param plugin recastJS plugin\n     * @param maxAgents the maximum agent count in the crowd\n     * @param maxAgentRadius the maximum radius an agent can have\n     * @param scene to attach the crowd to\n     * @returns the crowd you can add agents to\n     */\n    public constructor(plugin: RecastNavigationJSPluginV2, maxAgents: number, maxAgentRadius: number, scene: Scene) {\n        this._navigationPlugin = plugin;\n\n        if (!plugin.navMesh) {\n            throw new Error(\"There is no NavMesh generated.\");\n        }\n\n        this._recastCrowd = new (GetRecast().Crowd)(plugin.navMesh, {\n            maxAgents,\n            maxAgentRadius,\n        });\n\n        this._scene = scene;\n        this._engine = scene.getEngine();\n\n        this._onBeforeAnimationsObserver = scene.onBeforeAnimationsObservable.add(() => {\n            this.update(this._engine.getDeltaTime() * 0.001 * plugin.timeFactor);\n        });\n    }\n\n    /**\n     * Add a new agent to the crowd with the specified parameter a corresponding transformNode.\n     * You can attach anything to that node. The node position is updated in the scene update tick.","sourceCodeStart":94,"sourceCodeEnd":130,"githubUrl":"https://github.com/BabylonJS/Babylon.js/blob/0592b347b8a4ee0236089ea86a749cacfdb266d8/packages/dev/addons/src/navigation/plugin/RecastJSCrowd.ts#L94-L130","documentation":"RecastJSCrowd's constructor (RecastJSCrowd.ts:112) throws this when the supplied RecastNavigationJSPluginV2 has no navMesh (plugin.navMesh is undefined). The crowd needs an actual recast NavMesh object to construct the underlying @recast-navigation Crowd, so creating a crowd before any navmesh has been generated is impossible. This is an ordering error: crowd creation must follow a successful createNavMesh/createNavMeshAsync.","triggerScenarios":"Calling new RecastJSCrowd(plugin, maxAgents, maxAgentRadius, scene) before plugin.createNavMesh(...) / await plugin.createNavMeshAsync(...) succeeded, after a failed navmesh generation, or on a plugin whose createNavMesh was stubbed (e.g. the worker-mode plugin overrides createNavMesh to return null and never sets navMesh unless createNavMeshAsync completed).","commonSituations":"Calling createNavMesh without awaiting it (fire-and-forget on a promise), navmesh generation failing silently earlier, instantiating the crowd in scene-construction code that runs before async generation resolves, or using the worker plugin where only the sync createNavMesh was (invalidly) called.","solutions":["Generate the navmesh first and await it: await plugin.createNavMeshAsync(meshes, params) (or plugin.createNavMesh(meshes, params)), then construct the crowd.","Check plugin.navMesh is set before creating the crowd; if undefined, the earlier generation failed — fix that first.","If using CreateNavigationPluginWorkerAsync, only use createNavMeshAsync (sync createNavMesh is disabled and logs a warning, never populating navMesh).","Restructure initialization so crowd creation happens in the async continuation after generation resolves, not before."],"exampleFix":"// before\nconst plugin = await CreateNavigationPluginAsync();\nconst crowd = new RecastJSCrowd(plugin, 10, 0.5, scene); // throws: no navMesh yet\nawait plugin.createNavMeshAsync(meshes, params);\n\n// after\nconst plugin = await CreateNavigationPluginAsync();\nawait plugin.createNavMeshAsync(meshes, params);\nif (!plugin.navMesh) throw new Error(\"navmesh generation failed\");\nconst crowd = new RecastJSCrowd(plugin, 10, 0.5, scene);","handlingStrategy":"validation","validationCode":"// Run BEFORE constructing the crowd\nif (!plugin.navMesh) {\n    throw new Error(\"Create a navmesh (await plugin.createNavMeshAsync(...)) before creating a crowd\");\n}\nconst crowd = new RecastJSCrowd(plugin, maxAgents, maxAgentRadius, scene);","typeGuard":"function hasNavMesh(plugin: RecastNavigationJSPluginV2): plugin is RecastNavigationJSPluginV2 & { navMesh: NonNullable<RecastNavigationJSPluginV2[\"navMesh\"]> } {\n    return plugin.navMesh != null;\n}","tryCatchPattern":"let crowd: RecastJSCrowd;\ntry {\n    crowd = new RecastJSCrowd(plugin, 10, 0.5, scene);\n} catch (e) {\n    if (e instanceof Error && e.message.includes(\"no NavMesh generated\")) {\n        // generate navmesh then retry once\n        await plugin.createNavMeshAsync(meshes, params);\n        crowd = new RecastJSCrowd(plugin, 10, 0.5, scene);\n    } else { throw e; }\n}","preventionTips":["Always await navmesh generation before any dependent API (crowd, closestPoint, debug mesh).","Keep initialization in a single async setup function so ordering is explicit.","In worker mode use createNavMeshAsync only — sync createNavMesh is disabled and never sets navMesh.","Assert plugin.navMesh is non-null in dev builds before creating crowds."],"tags":["navigation","navmesh","crowd","initialization-order","recast"],"backgroundTag":"navmesh-not-generated","analyzedSha":"0592b347b8a4ee0236089ea86a749cacfdb266d8","analyzedAt":"2026-08-30T15:11:20.442Z","schemaVersion":2},"datasetVersion":"2026-08-30T18:17:15.746Z"}