{"record":{"id":"519054ed6dbc115c","repo":"plotly/plotly.js","slug":"something-went-wrong-during-this-id-fitbounds-comp","errorCode":null,"errorMessage":"Something went wrong during<this.id>fitbounds computations.","messagePattern":"Something went wrong during<this\\.id>fitbounds computations\\.","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"src/plots/geo/geo.js","lineNumber":328,"sourceCode":"\n    // scaleExtent uses fitScale so min/maxscale are relative to the\n    // user-facing projection.scale (where 1 == fits lon/lat ranges).\n    // https://d3js.org/d3-zoom#zoom_scaleExtent\n    projection.scaleExtent = () => {\n        const { minscale } = projLayout;\n        const maxscale = projLayout.maxscale ?? Infinity;\n        // swap if user supplied min > max so d3 receives a valid range\n        return [s * Math.min(minscale, maxscale), s * Math.max(minscale, maxscale)];\n    };\n\n    if (geoLayout.fitbounds) {\n        var b2 = projection.getBounds(makeRangeBox(axLon.range, axLat.range));\n        var k2 = Math.min((b[1][0] - b[0][0]) / (b2[1][0] - b2[0][0]), (b[1][1] - b[0][1]) / (b2[1][1] - b2[0][1]));\n\n        if (isFinite(k2)) {\n            projection.scale(k2 * s);\n        } else {\n            Lib.warn('Something went wrong during' + this.id + 'fitbounds computations.');\n        }\n    } else {\n        // adjust projection to user setting\n        projection.scale(projLayout.scale * s);\n    }\n\n    // px coordinates of view mid-point,\n    // useful to update `geo.center` after interactions\n    var midPt = (this.midPt = [(b[0][0] + b[1][0]) / 2, (b[0][1] + b[1][1]) / 2]);\n\n    projection.translate([t[0] + (midPt[0] - t[0]), t[1] + (midPt[1] - t[1])]).clipExtent(b);\n\n    // the 'albers usa' projection does not expose a 'center' method\n    // so here's this hack to make it respond to 'geoLayout.center'\n    if (geoLayout._isAlbersUsa) {\n        var centerPx = projection([center.lon, center.lat]);\n        // If center isn't within the Albers USA bounds (clipped to the USA),\n        // `projection(...)` returns null so skip the recentering","sourceCodeStart":310,"sourceCodeEnd":346,"githubUrl":"https://github.com/plotly/plotly.js/blob/1d090e0b5ffb8d0fdf6e0e4ff51d3f3cf67f1314/src/plots/geo/geo.js#L310-L346","documentation":"When fitting the geo projection to the data bounds (layout.geo.fitbounds or fitbounds: 'geo'), plotly.js computes a scale factor from projection bounds; if that factor is not finite (division by zero from degenerate bounds), it warns 'Something went wrong during<id>fitbounds computations.' and skips the scale adjustment, leaving the projection at its previous state.","triggerScenarios":"Enabling fitbounds on a geo subplot whose computed lon/lat ranges are degenerate (all points identical, empty data after filtering, or ranges producing zero-width/zero-height projection bounds so the scale ratio divides by zero).","commonSituations":"Fitting bounds to a single-point dataset; data filtered down to nothing; choropleth/geo traces with all locations invalid; fitbounds combined with manually set range that collapses to one point.","solutions":["Check that the geo data actually spans a non-degenerate lon/lat extent before enabling fitbounds.","Remove explicit range settings on axLon/axLat that collapse the bounds, and let fitbounds compute from full data.","Fall back to manual projection.scale/center configuration instead of fitbounds for degenerate datasets.","Validate/repair locations and coordinates (drop nulls, fix invalid ISO codes) so ranges are finite."],"exampleFix":"// before\nlayout = {geo: {fitbounds: 'locations'}, /* data reduced to a single point */}\n// after\n// ensure >= 2 distinct points, or set manually:\nlayout = {geo: {projection: {scale: 3}, center: {lon: 10, lat: 50}}};","handlingStrategy":"fallback","validationCode":"function hasNonDegenerateBounds(lon, lat) {\n  const lonSet = new Set(lon.filter(Number.isFinite));\n  const latSet = new Set(lat.filter(Number.isFinite));\n  return lonSet.size > 1 && latSet.size > 1;\n}\nconst layout = hasNonDegenerateBounds(lons, lats) ? {geo: {fitbounds: 'locations'}} : {geo: {projection: {scale: 2}}};","typeGuard":"const fitboundsSafe = (lons, lats) => lons.every(Number.isFinite) && lats.every(Number.isFinite) && new Set(lons).size > 1 && new Set(lats).size > 1;","tryCatchPattern":"try {\n  Plotly.newPlot(gd, data, {geo: {fitbounds: 'locations'}});\n} catch (e) {\n  if (/fitbounds/.test(e.message)) {\n    Plotly.newPlot(gd, data, {geo: {projection: {scale: 2}, center: {lon: 0, lat: 0}}});\n  } else { throw e; }\n}","preventionTips":["Verify data spans a real geographic extent before enabling fitbounds.","Filter out null/invalid coordinates and unmatched locations.","Avoid combining fitbounds with manually collapsed axis ranges.","Provide a manual projection.scale/center fallback for degenerate datasets."],"tags":["geo","fitbounds","projection"],"backgroundTag":"fitbounds-computation-failed","analyzedSha":"1d090e0b5ffb8d0fdf6e0e4ff51d3f3cf67f1314","analyzedAt":"2026-09-02T22:03:39.906Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T02:17:09.455Z"}