Crosstalk-Solutions/project-nomad · error · Error
Base styles file not found in storage/maps
Error message
Base styles file not found in storage/maps
What it means
After confirming base assets exist, generateStylesJSON reads the base styles JSON file via getFile. If the read returns falsy (file deleted between the existence check and the read, empty file, or the existence check passing via cache while the file is actually gone), this error is thrown.
Source
Thrown at admin/app/services/map_service.ts:355
const contentLength = response.headers['content-length']
const size = contentLength ? parseInt(contentLength.toString(), 10) : 0
return { filename, size }
} catch (error: any) {
logger.error({ err: error }, '[MapService] Preflight check failed for URL')
return { message: 'Preflight check failed. Please verify the URL is valid and accessible.' }
}
}
async generateStylesJSON(host: string | null = null, protocol: string = 'http'): Promise<BaseStylesFile> {
if (!(await this.checkBaseAssetsExist())) {
throw new Error('Base map assets are missing from storage/maps')
}
const baseStylePath = join(this.baseDirPath, this.baseStylesFile)
const baseStyle = await getFile(baseStylePath, 'string')
if (!baseStyle) {
throw new Error('Base styles file not found in storage/maps')
}
const rawStyles = JSON.parse(baseStyle.toString()) as BaseStylesFile
const regions = (await this.listRegions()).files
/** If we have the host, use it to build public URLs, otherwise we'll fallback to defaults
* This is mainly useful because we need to know what host the user is accessing from in order to
* properly generate URLs in the styles file
* e.g. user is accessing from "example.com", but we would by default generate "localhost:8080/..." so maps would
* fail to load.
*/
const sources = this.generateSourcesArray(host, regions, protocol)
const baseUrl = this.getPublicFileBaseUrl(host, this.basemapsAssetsDir, protocol)
const styles = await this.generateStylesFile(
rawStyles,
sources,View on GitHub (pinned to 0bd1c6f4f9)
Solutions
- Check that the base styles file exists and is non-empty in storage/maps; restore or re-provision it
- Re-run the full base asset provisioning step to rewrite the file atomically
- If it recurs under load, call checkBaseAssetsExist(false) to bypass the cache before generating styles
Defensive patterns
Strategy: retry
Validate before calling
const path = join(storageDir, 'styles.json') const stat = await fs.promises.stat(path).catch(() => null) if (!stat || stat.size === 0) await mapService.ensureBaseAssets()
Try / catch
try { return await mapService.generateStylesJSON(host) } catch (e) { if (e instanceof Error && e.message.includes('Base styles file not found')) { await mapService.ensureBaseAssets(); return mapService.generateStylesJSON(host) } throw e } Prevention
- Write provisioned files atomically (tmp + rename) so partial files never appear
- Bypass the existence-check cache (pass useCache=false) after deployments
- Alert on 0-byte files in storage/maps
When it happens
Trigger: Race condition where storage/maps assets are deleted or replaced while a styles request is in flight; an empty (0-byte) base styles file; a stale cache in checkBaseAssetsExist(useCache=true) hiding a missing file.
Common situations: Concurrent deployment pruning storage; partially-written file after an interrupted provisioning step; file permissions letting stat succeed but read fail/return empty.
Related errors
- Base map assets are missing from storage/maps
- Storage drive not available: cannot write to ${STORAGE_BASE}
- Base map assets are missing and could not be downloaded. Ple
- Error scanning and syncing storage
AI-assisted analysis of Crosstalk-Solutions/project-nomad@0bd1c6f4f9 (2026-08-27).
Data as JSON: /api/errors/0d1dbaa002ce418b.
Report an issue: GitHub.