Crosstalk-Solutions/project-nomad · error · Error
pmtiles extract for world basemap failed: ${err.message}. st
Error message
pmtiles extract for world basemap failed: ${err.message}. stderr: ${err.stderr ?? ''} What it means
Setting up the world basemap runs a 'pmtiles extract' subprocess (with a timeout and buffer cap) to carve a smaller world basemap out of a downloaded source. If the child process errors, times out, or exceeds maxBuffer, the partial output file is deleted and this error wraps the subprocess message and stderr.
Source
Thrown at admin/app/services/map_service.ts:487
const args = buildPmtilesExtractArgs({
sourceUrl: info.url,
outputFilepath: filepath,
maxzoom: WORLD_BASEMAP_MAX_ZOOM,
downloadThreads: 4,
})
logger.info(
`[MapService] Extracting world basemap (z0-${WORLD_BASEMAP_MAX_ZOOM}) from ${info.url}`
)
try {
await execFileAsync(PMTILES_BINARY_PATH, args, {
timeout: WORLD_BASEMAP_EXTRACT_TIMEOUT_MS,
maxBuffer: DRY_RUN_MAX_BUFFER,
})
this.worldBasemapReady = true
} catch (err: any) {
await deleteFileIfExists(filepath)
throw new Error(
`pmtiles extract for world basemap failed: ${err.message}. stderr: ${err.stderr ?? ''}`
)
}
}
private async checkBaseAssetsExist(useCache: boolean = true): Promise<boolean> {
// Return cached result if available and caching is enabled
if (useCache && this.baseAssetsExistCache !== null) {
return this.baseAssetsExistCache
}
await ensureDirectoryExists(this.baseDirPath)
const baseStylePath = join(this.baseDirPath, this.baseStylesFile)
const basemapsAssetsPath = join(this.baseDirPath, this.basemapsAssetsDir)
const [baseStyleExists, basemapsAssetsExists] = await Promise.all([
getFileStatsIfExists(baseStylePath),View on GitHub (pinned to 0bd1c6f4f9)
Solutions
- Read the embedded stderr in the message — it usually names the exact cause (ENOENT for missing binary, memory/disk messages, etc.)
- Verify the pmtiles CLI is installed and on PATH: pmtiles --version
- Increase WORLD_BASEMAP_EXTRACT_TIMEOUT_MS / DRY_RUN_MAX_BUFFER on slow or memory-constrained hosts
- Delete the source .pmtiles so it re-downloads, in case the input is corrupted
Defensive patterns
Strategy: retry
Validate before calling
import { execFile } from 'child_process'
const ok = await new Promise<boolean>(res => execFile('pmtiles', ['--version'], t => res(!t)))
if (!ok) throw new Error('pmtiles CLI not available') Try / catch
try { await mapService.ensureWorldBasemap() } catch (e) { if (e instanceof Error && e.message.includes('pmtiles extract')) { logger.error(e.message) /* parse stderr, fix env, retry once */ } throw e } Prevention
- Verify pmtiles CLI presence in container health checks
- Provision the world basemap during build/deploy, not on first request
- Tune extract timeout/maxBuffer for your host's disk and memory
- Free disk space monitoring on the storage volume
When it happens
Trigger: The pmtiles CLI not installed or not on PATH; the extract exceeding WORLD_BASEMAP_EXTRACT_TIMEOUT_MS; output exceeding DRY_RUN_MAX_BUFFER; corrupted source .pmtiles; disk full during extract.
Common situations: Docker images missing the pmtiles binary; low-memory containers hitting the buffer cap; slow disk/network making extraction exceed the timeout; truncated source download from a flaky CDN.
Related errors
- Invalid PMTiles file URL: ${url}. URL must end with .pmtiles
- Could not determine filename from URL
- Base map assets are missing and could not be downloaded. Ple
- Base map assets are missing from storage/maps
AI-assisted analysis of Crosstalk-Solutions/project-nomad@0bd1c6f4f9 (2026-08-27).
Data as JSON: /api/errors/6a59b7f2e330d35c.
Report an issue: GitHub.