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

  1. Check that the base styles file exists and is non-empty in storage/maps; restore or re-provision it
  2. Re-run the full base asset provisioning step to rewrite the file atomically
  3. 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

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


AI-assisted analysis of Crosstalk-Solutions/project-nomad@0bd1c6f4f9 (2026-08-27). Data as JSON: /api/errors/0d1dbaa002ce418b. Report an issue: GitHub.