Crosstalk-Solutions/project-nomad · error · Error
No protomaps builds found
Error message
No protomaps builds found
What it means
getGlobalMapInfo fetches the protomaps builds metadata JSON from PROTOMAPS_BUILDS_METADATA_URL and expects a non-empty array of {key,size} entries. If the endpoint returns an empty array (or a falsy body after a 200), this error is thrown because there is no build to download.
Source
Thrown at admin/app/services/map_service.ts:633
template.layers.push(layer)
}
template.sources = Object.assign(template.sources, source)
}
template.sprite = sprites
template.glyphs = glyphs
return template
}
async getGlobalMapInfo(): Promise<ProtomapsBuildInfo> {
const { default: axios } = await import('axios')
const response = await axios.get(PROTOMAPS_BUILDS_METADATA_URL, { timeout: 15000 })
const builds = response.data as Array<{ key: string; size: number }>
if (!builds || builds.length === 0) {
throw new Error('No protomaps builds found')
}
// Latest build first
const sorted = builds.sort((a, b) => b.key.localeCompare(a.key))
const latest = sorted[0]
const dateStr = latest.key.replace('.pmtiles', '')
const date = `${dateStr.slice(0, 4)}-${dateStr.slice(4, 6)}-${dateStr.slice(6, 8)}`
return {
url: `${PROTOMAPS_BUILD_BASE_URL}/${latest.key}`,
date,
size: latest.size,
key: latest.key,
}
}
async downloadGlobalMap(): Promise<{ filename: string; jobId?: string }> {View on GitHub (pinned to 0bd1c6f4f9)
Solutions
- Check what the metadata URL actually returns: curl -s $PROTOMAPS_BUILDS_METADATA_URL
- Handle a wrapped response shape if upstream changed (e.g. response.data.builds)
- Retry after a transient upstream issue; pin/upgrade to a version matching the current protomaps API
- If self-hosting, point PROTOMAPS_BUILDS_METADATA_URL at a known-good mirror
Example fix
// before
const builds = response.data as Array<{ key: string; size: number }>
// after
const data: any = response.data
const builds = (Array.isArray(data) ? data : data?.builds) as Array<{ key: string; size: number }> Defensive patterns
Strategy: retry
Validate before calling
const { data } = await axios.get(PROTOMAPS_BUILDS_METADATA_URL, { timeout: 15000 })
const builds = Array.isArray(data) ? data : data?.builds
if (!builds?.length) throw new Error('no builds available; retry later') Type guard
const isBuildList = (d: unknown): d is Array<{ key: string; size: number }> => Array.isArray(d) && d.every(b => typeof b?.key === 'string') Try / catch
try { return await mapService.getGlobalMapInfo() } catch (e) { if (e instanceof Error && e.message === 'No protomaps builds found') { await delay(10_000); return mapService.getGlobalMapInfo() } throw e } Prevention
- Add exponential-backoff retries around upstream metadata calls
- Pin to a known build key instead of always resolving 'latest'
- Monitor the upstream protomaps builds endpoint for schema changes
When it happens
Trigger: Calling getGlobalMapInfo (directly or via downloadGlobalMap) when the upstream protomaps builds listing returns [] or an unexpected shape that evaluates as empty after casting.
Common situations: Upstream API format change (fields renamed, response wrapped in an object so the array cast yields nothing); temporary CDN hiccup returning an empty list; a proxy or mirror serving stale/empty metadata; axios returning a string body that is truthy but empty when parsed.
Related errors
- HTTP ${resp.status} from ${MANIFEST_URL}
- No internet — connect to download FDA drug data. (${msg})
- Failed to download tar file
- Base map assets are missing and could not be downloaded. Ple
- Failed to fetch available versions for this service.
AI-assisted analysis of Crosstalk-Solutions/project-nomad@0bd1c6f4f9 (2026-08-27).
Data as JSON: /api/errors/714d835c78e231f8.
Report an issue: GitHub.