{"record":{"id":"60413e1c261c5fa0","repo":"Crosstalk-Solutions/project-nomad","slug":"failed-to-download-tar-file","errorCode":null,"errorMessage":"Failed to download tar file","messagePattern":"Failed to download tar file","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"admin/app/services/map_service.ts","lineNumber":118,"sourceCode":"    const defaultTarFileURL = new URL(\n      this.baseAssetsTarFile,\n      'https://github.com/Crosstalk-Solutions/project-nomad-maps/raw/refs/heads/master/'\n    )\n\n    const resolvedURL = url ? new URL(url) : defaultTarFileURL\n    await doResumableDownloadWithRetry({\n      url: resolvedURL.toString(),\n      filepath: tempTarPath,\n      timeout: 30000,\n      max_retries: 2,\n      allowedMimeTypes: BASE_ASSETS_MIME_TYPES,\n      onAttemptError(error, attempt) {\n        console.error(`Attempt ${attempt} to download tar file failed: ${error.message}`)\n      },\n    })\n    const tarFileBuffer = await getFileStatsIfExists(tempTarPath)\n    if (!tarFileBuffer) {\n      throw new Error(`Failed to download tar file`)\n    }\n\n    await extract({\n      cwd: join(process.cwd(), this.mapStoragePath),\n      file: tempTarPath,\n      strip: 1,\n    })\n\n    await deleteFileIfExists(tempTarPath)\n\n    // Invalidate cache since we just downloaded new assets\n    this.baseAssetsExistCache = true\n\n    return true\n  }\n\n  async downloadCollection(slug: string): Promise<string[] | null> {\n    const manifestService = new CollectionManifestService()","sourceCodeStart":100,"sourceCodeEnd":136,"githubUrl":"https://github.com/Crosstalk-Solutions/project-nomad/blob/0bd1c6f4f9888d577fe232de06ac144bb8337131/admin/app/services/map_service.ts#L100-L136","documentation":"Thrown by MapService.downloadBaseAssets after a retrying download of the base map assets tarball: once the retry helper finishes, the code checks that the temp tar file exists on disk (getFileStatsIfExists) and throws if it was never created/kept. It means every download attempt failed or the file was cleaned up before verification.","triggerScenarios":"Calling downloadBaseAssets when the assets URL is unreachable, network egress is blocked, disk is full so the temp file can't be written, or the retry helper swallows failures and returns without writing tempTarPath.","commonSituations":"Offline/air-gapped environments, firewall blocking the CDN hosting the map tarball, misconfigured proxy env vars, full tmp volume, DNS failures — console.error shows per-attempt messages before this throw.","solutions":["Check the preceding console.error 'Attempt N to download tar file failed' lines for the root network cause","Verify egress connectivity to the assets URL from the host (curl -I <tar-url>)","Free space on the tmp/docs volume and confirm write permissions for the temp tar path","Configure HTTP(S)_PROXY correctly if behind a corporate proxy","Retry once network is restored — the operation is idempotent-ish (old extracted assets are only replaced on success)"],"exampleFix":"// before\nawait mapService.downloadBaseAssets() // throws: Failed to download tar file\n\n// after\n// verify reachability first\nawait assertReachable(ASSETS_URL) // curl-equivalent check\nawait mapService.downloadBaseAssets()","handlingStrategy":"retry","validationCode":"import { request } from 'undici'\ntry { await request(ASSETS_TAR_URL, { method: 'HEAD' }) } catch { /* pre-check */ throw new Error('assets CDN unreachable') }","typeGuard":null,"tryCatchPattern":"let lastErr: unknown\nfor (let i = 0; i < 3; i++) {\n  try { await mapService.downloadBaseAssets(); break }\n  catch (e) {\n    lastErr = e\n    if ((e as Error).message !== 'Failed to download tar file') throw e\n    await sleep(30_000 * (i + 1))\n  }\n}\nif (lastErr) throw lastErr","preventionTips":["Verify egress/proxy to the assets CDN during environment setup","Alert on disk-full conditions on the temp volume","Treat per-attempt console.error lines as the diagnostic source of truth"],"tags":["network","download","map-assets","retry"],"backgroundTag":"asset-download-failed","analyzedSha":"0bd1c6f4f9888d577fe232de06ac144bb8337131","analyzedAt":"2026-08-27T05:34:15.424Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}