Troubleshooting
Start with what the map itself says: in most cases it names the problem and the fix. Then find your symptom in the tables below; each row links to the page that explains it.
Reading what the map tells you
Section titled “Reading what the map tells you”<ml-map> and <ml-scrollytelling> (and the Astro components, which render
them) report problems on the page, not only in the browser console:
- Error card (replaces the map). The document can’t render at all: a
YAML syntax error, a validation error (with its line number and, for a
typo, a “did you mean”), a
srcfile that isn’t found (with the full address the browser requested; a wrong path that returns a web page is recognised as one), a page opened from a file (file://, which browsers block; the card says to start a local server), or a basemap style that won’t load. Fix what the card names and reload. For page scripts,mapReady()rejects. - Notice (over the map, dismissible). The map works but part of the
document didn’t load: a layer MapLibre rejected (for example a bad colour
inside an expression), a layer whose
source:names a source that doesn’t exist, a data file that didn’t load, or animages:entry or marker icon that failed. Each line names the layer or file. The notice is written for two readers: it leads with “Part of this map couldn’t load” for anyone visiting the site, and keeps the fix in a “Details for the site’s author” section below it, open while you develop and closed on a published site, where a click opens it. The map still firesml-map:load. - Author hints (in the same notice). The map works, but the document
probably doesn’t say what you meant: a “did you mean” for a near-miss name,
a key nested under
config:that belongs at the top level, afitTotypo, acenterorboundsthat looks written [latitude, longitude], abefore:naming a layer the map doesn’t have, a chapter naming a missing layer, a value starting with the reserved=. These are for you, not your visitors, so they show only while you develop (below). A notice holding only hints leads with “Notes for this map’s author”. - Height hint. A map with no height is invisible, so the element shows a short note saying to give it one, and removes it once the map has a height (The map has no height).
- “Loading map…” in the middle of the map. Not a problem report: while
the map starts, the element carries
aria-busy="true", and if it hasn’t drawn after about a second (usually a slow basemap, or afitTodata file still arriving) a small, muted “Loading map…” appears (role="status"). Both go away when the basemap draws or an error card replaces the map, so a fast map never shows it.quietdoesn’t hide it; a page with its own loading indicator hides it withml-map .ml-map-loading { display: none; }. The text is translatable asmaplibre-yaml.Loadinginlocale:(Accessibility & languages).
Everything is also written to the browser console, so open the developer
tools (F12, or Ctrl+Shift+I;
⌥+⌘+I on a Mac) when the page says nothing.
To catch mistakes before you load the page, run
npx maplibre-yaml validate map.yaml (The CLI) or
set up your editor to check the YAML as you type.
Page scripts can listen for the same problems as events
(ml-map:error and the others).
When are author hints shown?
Section titled “When are author hints shown?”Failures always show. Author hints show when any of these is true, and stay off the page otherwise:
| Situation | Author hints |
|---|---|
The page is served from your computer: localhost, 127.0.0.1, [::1], 0.0.0.0 or [::] (a dev server started with --host), or opened as a file:// page | shown |
A bundler development build: astro dev, vite (their import.meta.env.DEV), on any address, a Codespaces URL included | shown |
The element has the debug attribute (or its <ml-scrollytelling> does; in Astro, the debug prop) | shown, wherever the page is served |
| A published site (GitHub Pages, Netlify, your own domain), including the plain CDN script, which can’t know how it was built | hidden |
The element has quiet | hidden, and so are failures |
Every hint is still written to the browser console, wherever the page runs.
debug and quiet
Section titled “debug and quiet”To check a deployed site, add debug to see the author hints there:
<ml-map src="/maps/city.yaml" debug></ml-map>Add quiet to keep the notice (failures and hints) and the height hint off
the page, for a production site that would rather fail quietly. The problems
are still logged to the console and dispatched as events. quiet wins over
debug. The error card is always shown.
<ml-map src="/maps/city.yaml" quiet></ml-map>The Astro Map, FullPageMap and Scrollytelling components take the same
two as props: <Map src="…" debug />.
The map doesn’t show
Section titled “The map doesn’t show”| Symptom | Where to look |
|---|---|
| Nothing at all where the map should be, no error | The element has no height: The map has no height |
| A blank page, and Failed to resolve module specifier “maplibre-gl” in the console | The import map is missing: Browser usage (CDN) |
The page was opened by double-clicking the HTML file (a file:// address) | Serve the folder instead: Run a local server |
| A blank map and Worker failed to load | maplibre-gl 6 inside a bundler needs its worker set: Worker failed to load |
The element stays empty and customElements.get("ml-map") is undefined | <ml-map> isn’t defined |
| An error card (“Configuration Error”) | An error card instead of the map |
YAML syntax error … <!doctype html> after npm run build | The YAML is next to index.html instead of in public/: YAML next to index.html |
| The map refuses to load and says it has no basemap | Add mapStyle: under config:: Map styles |
| The map is in the ocean, or far from your data | Coordinates are [longitude, latitude]: Coordinates |
The map shows, but your data doesn’t
Section titled “The map shows, but your data doesn’t”| Symptom | Where to look |
|---|---|
| The basemap draws, your layer doesn’t | The basemap draws but your layer doesn’t |
| A data file on another site doesn’t load (a CORS error in the console) | CORS considerations |
| ”CSV files aren’t supported” | Convert the table to GeoJSON: CSV and spreadsheets |
| A colour is ignored, or the layer fails validation | Put colours in quotes: in YAML # starts a comment (Adding a simple layer) |
A warning about a value starting with = | Strings starting with = are reserved |
| A local data file isn’t found | Paths are relative to the page, not the YAML: Using your own data file |
| Your page’s JavaScript never sees the map’s events | Events not firing |
Works on your computer, not once published
Section titled “Works on your computer, not once published”| Symptom | Where to look |
|---|---|
| A 404 for the YAML or the data on GitHub Pages (or any site under a subpath) | Set the base: Publishing & subpaths (HTML pages, Astro) |
Every file 404s on your computer after adding base | Previewing a subpath |
| Author hints you saw while developing are gone | Expected: they show only while you develop; add debug to see them (above) |
| Something changed after upgrading | Upgrading to 0.9 |
Common problems in detail
Section titled “Common problems in detail”The map has no height
Section titled “The map has no height”What you see: nothing where the map should be, no error, or a map a few
pixels tall. Unless it has quiet, the element shows a short note asking for
a height.
<ml-map> has no size of its own, and neither does a <div> you hand to the
JavaScript API. Give it a height and display: block:
ml-map { display: block; /* required: a custom element is inline by default */ width: 100%; height: 400px; /* or 100vh to fill the window */}The Astro Map component sets a height for you (400px by default, the
height prop changes it), and FullPageMap fills the window. A component of
your own around <ml-map> needs both properties:
<ml-map src="/configs/map.yaml" style="height: 400px; display: block;" />.
<ml-map> isn’t defined
Section titled “<ml-map> isn’t defined”What you see: the element is on the page but stays empty, and
customElements.get("ml-map") in the console returns undefined.
The script that registers the element didn’t run:
- From a CDN: the page needs both the import map for
maplibre-gland theregister.jsscript, as in Browser usage (CDN). A Failed to resolve module specifier “maplibre-gl” error in the console means the import map is missing or comes after the script. - With a bundler: import
@maplibre-yaml/core/registerin code that runs in the browser (Using a bundler). - In Astro: import it in a
<script>tag, never in the frontmatter (HTMLElement is not defined), or use the package’s<Map>component, which does it for you.
Blank map and “Worker failed to load”
Section titled “Blank map and “Worker failed to load””What you see: the map area stays empty, or shows a Map Error card
saying Worker failed to load; the console names maplibre-gl-worker.mjs.
maplibre-gl 6 draws in a background worker loaded from a separate file, and inside a bundle (Vite, Astro, webpack) it can’t find that file unless it is told where it is. Add the worker lines next to the register import:
import { setWorkerUrl } from "maplibre-gl";import workerUrl from "maplibre-gl/dist/maplibre-gl-worker.mjs?worker&url";import "@maplibre-yaml/core/register";
setWorkerUrl(workerUrl);The CDN page needs nothing (the worker loads from the CDN), and on
maplibre-gl 4 or 5 leave these lines out. The @maplibre-yaml/astro
components set the worker for you; a component of your own around <ml-map>
does it in its <script>
(Using <ml-map> directly).
Details: Using a bundler (Vite).
An error card instead of the map
Section titled “An error card instead of the map”What you see: a card in place of the map (for example “Configuration
Error”) listing the problem with its line, such as
id: The document is missing id: — add id: a-short-name.
The document failed to load, parse or validate. The card names the field; the common causes:
-
Indentation. YAML nests by indentation: use spaces (two per level), never tabs, and keep sibling keys at the same depth.
# Wrong: zoom is indented differently from centerconfig:center: [-74, 40]zoom: 10 -
A missing required key. A map needs
type: map, anid, and aconfig:withcenterandzoom; withoutmapStyle(the basemap) it warns in validation and the page shows an error card.type: mapid: my-mapconfig:center: [-74.006, 40.7128]zoom: 10mapStyle: "https://tiles.openfreemap.org/styles/liberty"layers: [] -
A wrong value.
centeris[longitude, latitude](two numbers), not a place name; colours go in quotes, because in YAML#starts a comment. -
A file that isn’t found. The card shows the address the browser asked for. Paths are relative to the page, or under
public/with a bundler or Astro; on a site under a subpath, see Publishing & subpaths.
YAML inside a JavaScript template literal or a <script type="text/yaml">
tag has its own indentation pitfall:
Template literal YAML issues.
The basemap draws but your layer doesn’t
Section titled “The basemap draws but your layer doesn’t”First read the notice at the top of the map, if there is one: it names each layer that didn’t draw and each data file that didn’t load, with the address the browser tried. Then check:
-
The path. Relative data paths resolve against the page, not the YAML file (Using your own data file). On a site under a subpath, set
base(Publishing & subpaths). -
The file. Open its URL in the browser: it should be GeoJSON, not a web page or a 404. In the developer tools’ Network tab, find the request.
-
CORS. A file on another site must allow your page to read it; the console shows a CORS error if not (CORS considerations).
-
The features. A file with no features, or features without geometry, loads but draws nothing. Page scripts can log what loaded:
const mapEl = document.querySelector("ml-map");mapEl.addEventListener("ml-map:layer-data-loaded", (e) =>console.log("Loaded:", e.detail.layerId, e.detail.featureCount));mapEl.addEventListener("ml-map:layer-data-error", (e) =>console.error("Error:", e.detail.layerId, e.detail.error)); -
The style. A colour without quotes, a
filter:that matches nothing, or aminzoomabove the current zoom hide a layer that did load.
Large data: PMTiles, FlatGeobuf, GeoParquet and COG
Section titled “Large data: PMTiles, FlatGeobuf, GeoParquet and COG”When one of these files fails, the rest of the map still draws and the notice says why. The common messages, with the fix for each, are in When something goes wrong.
| Symptom | Where to look |
|---|---|
”served without range-request support”, often with python -m http.server | Use a server with range requests (npx serve, GitHub Pages, Netlify, S3): Range requests and CORS |
| A 416 status (Range Not Satisfiable) | The file was found, but the server refused the part asked for: the upload may be incomplete, or the server doesn’t serve parts of files correctly. Upload the file again, or try another host (Range requests and CORS) |
| A file on another site is blocked (CORS) | The other server must allow your site and the Range header: CORS rule |
| ”is in EPSG:…” (the wrong projection) | FlatGeobuf needs longitude/latitude (EPSG:4326), a COG Web Mercator (EPSG:3857); the notice gives the command that converts it (details) |
“The … reader (…/chunks/….js) couldn’t be downloaded”, on a site hosting maplibre-yaml’s files itself | Copy the whole dist/ folder, not only register.js: Hosting the files yourself |
| A Protomaps basemap draws without labels or icons, or the notice names the fonts or icons | Labels come from Protomaps’ font host unless you copy them: Host your own basemap |
| ”too large to load whole in a browser” | Add load: viewport or convert the file: When something goes wrong |
| Symptom | Where to look |
|---|---|
ReferenceError: HTMLElement is not defined | HTMLElement is not defined |
A saved YAML change doesn’t appear in astro dev | Editing in astro dev |
<Map src> gives a 404 | src is the address on the site, without public/: Incorrect src path |
A page using loadMapConfig fails with ENOENT on a server | Server output (SSR) |
| More Astro problems | Astro troubleshooting |
| Symptom | Where to look |
|---|---|
mlym: command not found, or npx mlym fails with a 404 | Use npx maplibre-yaml, or install the CLI: Short alias, Command not found |
| No autocomplete or checking in your editor | Editor setup |
mlym validate errors don’t show in VS Code’s Problems panel | Validate on save (VS Code task) |