Dash 2.4.1 - Uncaught (in promise) Error: Mapbox error

I’ve created a test environment that is a copy/paste of Part 2. Layout | Dash for Python Documentation | Plotly

I create a simple callback for example-graph to respond to relayoutData. Everything works.

I switch example-graph layout to the simplest mapbox figure. The map is rendered in the browser correctly. The callback no longer works however. relayoutData, clickData etc…

The only errors anywhere are on the console: Uncaught (in promise) Error: Mapbox error.

I can have the callback print to console clickData, attach dummy clickData to the dcc.Graph and make prevent_initial_call=False and see my dummy data in the stdout on initial load, so I know the the callback is registering

Brotli==1.0.9
click==8.1.3
dash==2.4.1
dash-core-components==2.0.0
dash-html-components==2.0.0
dash-table==5.0.0
Flask==2.1.2
Flask-Compress==1.12
importlib-metadata==4.11.4
itsdangerous==2.1.2
Jinja2==3.1.2
MarkupSafe==2.1.1
numpy==1.22.4
pandas==1.4.2
plotly==5.8.0
python-dateutil==2.8.2
pytz==2022.1
six==1.16.0
tenacity==8.0.1
Werkzeug==2.1.2
zipp==3.8.0
1 Like

hi @crachel
can you please share a minimal reproducible example? One that will allow us to reproduce your error locally on our computer.

I removed my accesstoken/style … but this is the code below. If I switch the dcc.Graph to equal px.bar, the relayoutData callback prints to stdout. If it’s the mapbox figure, nothing.

from dash import Dash, ctx, html, dcc, Input, Output
from dash.exceptions import PreventUpdate
import plotly.express as px
import pandas as pd

from plotly.graph_objects import Scattermapbox
from plotly.graph_objs.layout import Margin

app = Dash(__name__)

# assume you have a "long-form" data frame
# see https://plotly.com/python/px-arguments/ for more options
df = pd.DataFrame({
    "Fruit": ["Apples", "Oranges", "Bananas", "Apples", "Oranges", "Bananas"],
    "Amount": [4, 1, 2, 2, 4, 5],
    "City": ["SF", "SF", "SF", "Montreal", "Montreal", "Montreal"]
})

fig = px.bar(df, x="Fruit", y="Amount", color="City", barmode="group")

app.layout = html.Div(children=[
    html.H1(children='Hello Dash'),

    html.Div(id='test-div', children='''
        Dash: A web application framework for your data.
    '''),

    dcc.Graph(
        id='example-graph',
		clickData={
			'points': [{'text': 'null'}] # used during initial load of app
		},
        figure=dict(
            data=[Scattermapbox()], 
            layout=dict(
                uirevision=False,
                autosize = True,
                margin = Margin(l=0, r=0, t=0, b=0),
                showlegend = True,
                legend=dict(font=dict(size=10), orientation='h'),
                xaxis=dict(hoverformat='.5f'),
                yaxis=dict(hoverformat='.5f'),
                mapbox = dict(
                    accesstoken = YOURACCESSTOKEN,
                    style = YOURSTYLE,
                    center = dict(lon=-100.450278, lat=31.442778),
                    zoom = 4.5,
                )
            )
        ), 
    )
])

@app.callback(
    Output('test-div', 'className'),
    [Input('example-graph', 'relayoutData')]
)
def update_from_report_operator_map_clickdata(clickData):	
	prop_id = ctx.triggered[0]['prop_id']
	print(prop_id)
	print (clickData)
	raise PreventUpdate


if __name__ == '__main__':
    app.run_server(host='172.31.44.74',debug=True,port=8050)

hi @crachel
When using open-street-map template, I get the relayoutData printed. For example, I get:

{‘mapbox.center’: {‘lon’: -99.88767635096002, ‘lat’: 33.130783012662036}, ‘mapbox.zoom’: 4.5, ‘mapbox.bearing’: 0, ‘mapbox.pitch’: 0, ‘mapbox._derived’: {‘coordinates’: [[-114.52354376038313, 38.785437325640004], [-85.25180894153786, 38.785437325640004], [-85.25180894153786, 27.08718413770059], [-114.52354376038313, 27.08718413770059]]}}

When I use your last piece of code, using open street map:

from dash import Dash, ctx, html, dcc, Input, Output
from dash.exceptions import PreventUpdate
import plotly.express as px
import pandas as pd

from plotly.graph_objects import Scattermapbox
from plotly.graph_objs.layout import Margin

app = Dash(__name__)

# assume you have a "long-form" data frame
# see https://plotly.com/python/px-arguments/ for more options
# df = pd.DataFrame({
#     "Fruit": ["Apples", "Oranges", "Bananas", "Apples", "Oranges", "Bananas"],
#     "Amount": [4, 1, 2, 2, 4, 5],
#     "City": ["SF", "SF", "SF", "Montreal", "Montreal", "Montreal"]
# })
#
# fig = px.bar(df, x="Fruit", y="Amount", color="City", barmode="group")

app.layout = html.Div(children=[
    html.H1(children='Hello Dash'),

    html.Div(id='test-div', children='''
        Dash: A web application framework for your data.
    '''),

    dcc.Graph(
        id='example-graph',
		clickData={
			'points': [{'text': 'null'}] # used during initial load of app
		},
        figure=dict(
            data=[Scattermapbox()],
            layout=dict(
                uirevision=False,
                autosize = True,
                margin = Margin(l=0, r=0, t=0, b=0),
                showlegend = True,
                legend=dict(font=dict(size=10), orientation='h'),
                xaxis=dict(hoverformat='.5f'),
                yaxis=dict(hoverformat='.5f'),
                mapbox = dict(
                    # accesstoken = YOURACCESSTOKEN,
                    style = "open-street-map",
                    center = dict(lon=-100.450278, lat=31.442778),
                    zoom = 4.5,
                )
            )
        ),
    )
])

@app.callback(
    Output('test-div', 'className'),
    [Input('example-graph', 'relayoutData')]
)
def update_from_report_operator_map_clickdata(clickData):
	prop_id = ctx.triggered[0]['prop_id']
	print(prop_id)
	print (clickData)
	raise PreventUpdate


if __name__ == '__main__':
    app.run_server(debug=True,port=8050)


thanks @adamschroeder I get the same results. When I add back the accesstoken and add my mapbox style, the console errors and no callbacks return.

I downgraded all the packages to match another app I have that mapbox and the associated callbacks work on and it mysteriously still does not work.

these are the console errors:

Uncaught (in promise) Error: Mapbox error.
    r async-plotlyjs.js:2
    fire async-plotlyjs.js:2
    fire async-plotlyjs.js:2
    _validateLayer async-plotlyjs.js:2
    r async-plotlyjs.js:2
    fire async-plotlyjs.js:2
    fire async-plotlyjs.js:2
    fire async-plotlyjs.js:2
    _tileJSONRequest async-plotlyjs.js:2
    i async-plotlyjs.js:2
    c async-plotlyjs.js:2
    promise callback*c async-plotlyjs.js:2
    l async-plotlyjs.js:2
    promise callback*l async-plotlyjs.js:2
    vt async-plotlyjs.js:2
    vt async-plotlyjs.js:2
    getJSON async-plotlyjs.js:2
    A async-plotlyjs.js:2
    load async-plotlyjs.js:2
    onAdd async-plotlyjs.js:2
    onAdd async-plotlyjs.js:2
    addSource async-plotlyjs.js:2
    _load async-plotlyjs.js:2
    _request async-plotlyjs.js:2
    c async-plotlyjs.js:2
    promise callback*c async-plotlyjs.js:2
    l async-plotlyjs.js:2
    promise callback*l async-plotlyjs.js:2
    vt async-plotlyjs.js:2
    vt async-plotlyjs.js:2
    getJSON async-plotlyjs.js:2
    loadURL async-plotlyjs.js:2
    _updateStyle async-plotlyjs.js:2
    setStyle async-plotlyjs.js:2
    i async-plotlyjs.js:2
    createMap async-plotlyjs.js:2
    n async-plotlyjs.js:2
    plot async-plotlyjs.js:2
    plot async-plotlyjs.js:2
    drawData async-plotlyjs.js:2
    syncOrAsync async-plotlyjs.js:2
    _doPlot async-plotlyjs.js:2
    newPlot async-plotlyjs.js:2
    react async-plotlyjs.js:2
    React 2
    commitLifeCycles react-dom@16.v2_0_0m1653315825.14.0.js:19949
    commitLayoutEffects react-dom@16.v2_0_0m1653315825.14.0.js:22938
    callCallback react-dom@16.v2_0_0m1653315825.14.0.js:182
    invokeGuardedCallbackDev react-dom@16.v2_0_0m1653315825.14.0.js:231
    invokeGuardedCallback react-dom@16.v2_0_0m1653315825.14.0.js:286
    commitRootImpl react-dom@16.v2_0_0m1653315825.14.0.js:22676
    unstable_runWithPriority react@16.v2_0_0m1653315825.14.0.js:2685
    runWithPriority$1 react-dom@16.v2_0_0m1653315825.14.0.js:11174
    commitRoot react-dom@16.v2_0_0m1653315825.14.0.js:22516
    finishSyncRender react-dom@16.v2_0_0m1653315825.14.0.js:21942

Just to follow up here this does NOT appear to be a problem with plotly/dash

the Mapbox style I’m using apparently has errors. Don’t know what exactly but based on the the console error, possibly missing SpriteImages. Anyway, I switched the style to a Mapbox default one, and callbacks function correctly. I will investigate the style issue with mapbox

1 Like

If you see the error Mapbox.h not found, this can typically be resolved by building your application despite the error.

If you’re using version v6.0.0 of the SDK or later, you will need to authorize your download of the Maps SDK with a secret access token with the DOWNLOADS:READ scope. Otherwise, you will see the following error:

[!] Error installing MapboxMaps
curl: (22) The requested URL returned error: 401 Unauthorized
To resolve this, create a secret access token from your Mapbox account and follow the instructions outlined in the installation guide to configure your secret token.

Regards,
Rachel Gomez