BabylonJS/Babylon.js · error · Error

Unable to generateSoloNavMesh: ${result.error}

Error message

Unable to generateSoloNavMesh: ${result.error}

What it means

After dispatching to the Recast WASM generator (solo, tiled, or tile cache depending on parameters), GenerateNavMesh() checks result.success and throws if the underlying @recast-navigation generator reported failure (generator.single-thread.ts:59). The message template says "generateSoloNavMesh" even for tiled/tile-cache paths, but result.error carries the actual Recast failure reason. This indicates Recast could not build a valid nav mesh from the provided geometry/config — e.g. invalid parameters, geometry outside the tile/bounds extents, or an internal Recast error.

Source

Thrown at packages/dev/addons/src/navigation/generator/generator.single-thread.ts:59

    const tileSize = parameters.tileSize ?? 0;
    const needsTileCache = (parameters.maxObstacles ?? 0) > 0;
    const needsTiledNavMesh = tileSize > 0;
    if (needsTileCache) {
        if (tileSize < 32 || tileSize > 64) {
            Logger.Warn("NavigationPlugin: Tile cache is enabled. Recommended tileSize is 32 to 64. Other values may lead to unexpected behavior.");
        }
    }

    // Create the appropriate configuration based on the parameters
    const config = needsTileCache ? CreateTileCacheNavMeshConfig(parameters) : needsTiledNavMesh ? CreateTiledNavMeshConfig(parameters) : CreateSoloNavMeshConfig(parameters);
    const result = needsTileCache
        ? recast.generateTileCache(positions, indices, config as TileCacheGeneratorConfig, parameters.keepIntermediates)
        : needsTiledNavMesh
          ? recast.generateTiledNavMesh(positions, indices, config as TiledNavMeshGeneratorConfig, parameters.keepIntermediates)
          : recast.generateSoloNavMesh(positions, indices, config as SoloNavMeshGeneratorConfig, parameters.keepIntermediates);

    if (!result.success) {
        throw new Error(`Unable to generateSoloNavMesh: ${result.error}`);
    }

    return {
        navMesh: result.navMesh,
        intermediates: result.intermediates,
        navMeshQuery: new recast.NavMeshQuery(result.navMesh),
        tileCache: "tileCache" in result ? result.tileCache : undefined,
    };
}

View on GitHub (pinned to 0592b347b8)

Solutions

  1. Read result.error in the message for the actual Recast cause and fix that specific issue first
  2. Check triangle winding: if the nav mesh comes out empty, set doNotReverseIndices: true (or remove it) in INavMeshParametersV2 to match your mesh winding
  3. Keep tileSize in the recommended 32–64 range when using tile cache (maxObstacles > 0), as warned at generator.single-thread.ts:46
  4. Validate your config scale: cellSize/cellHeight/agentRadius/agentHeight/agentMaxClimb and the bounds must match your scene units
  5. Simplify: try generating a solo nav mesh (no tileSize, no maxObstacles) on a single simple mesh to isolate whether the issue is config or geometry

Example fix

// before
plugin.createNavMesh(meshes, {
    tileSize: 128,          // outside recommended range for tile cache
    maxObstacles: 10,
    doNotReverseIndices: true, // wrong for this winding
});

// after
plugin.createNavMesh(meshes, {
    tileSize: 64,               // within recommended 32-64
    maxObstacles: 10,
    doNotReverseIndices: false, // correct winding for the source meshes
});
Defensive patterns

Strategy: validation

Validate before calling

function validateNavMeshParameters(p: INavMeshParametersV2) {
    const tileSize = p.tileSize ?? 0;
    if ((p.maxObstacles ?? 0) > 0 && (tileSize < 32 || tileSize > 64)) {
        throw new Error("tileSize must be 32-64 when maxObstacles > 0");
    }
    if (!p.cellSize || p.cellSize <= 0 || !p.agentRadius || p.agentRadius <= 0) {
        throw new Error("Invalid nav mesh config: cellSize/agentRadius must be positive");
    }
}

Type guard

function isGenerationSuccess(r: { success: boolean; error?: string }): r is { success: true; error?: never } {
    return r.success === true;
}

Try / catch

try {
    const { navMesh, navMeshQuery } = GenerateNavMesh(meshes, parameters);
} catch (e) {
    if (e instanceof Error && e.message.startsWith("Unable to generateSoloNavMesh")) {
        console.error("Recast failed:", e.message);
        // retry with corrected winding: parameters.doNotReverseIndices = !parameters.doNotReverseIndices
    }
}

Prevention

When it happens

Trigger: parameters.tileSize > 0 with geometry extents incompatible with the tile config; maxObstacles > 0 with tileSize outside the recommended 32–64 range; SoloNavMeshGeneratorConfig values (cellSize, agentRadius, agentHeight, agentMaxClimb, bounds) too large/small or misaligned for the scene scale; geometry with degenerate/inverted triangles; doNotReverseIndices set wrong so triangles have incorrect winding and Recast culls them all; Recast internal errors reported via result.error.

Common situations: Scene scaled very differently from Recast defaults (tiny or huge units) making cellSize/agent values nonsensical; wrong triangle winding after exporting from a DCC tool without the doNotReverseIndices flag; tileSize/maxObstacles combinations warned about at line 46 but not fatal until generation; copying config from another project whose scene scale differs.

Related errors


AI-assisted analysis of BabylonJS/Babylon.js@0592b347b8 (2026-08-30). Data as JSON: /api/errors/688fad56072f618b. Report an issue: GitHub.