{"record":{"id":"44d90ed1e660adc5","repo":"mastra-ai/mastra","slug":"unsupported-file-extension-targzpath","errorCode":null,"errorMessage":"Unsupported file extension: ${targzPath}","messagePattern":"Unsupported file extension: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/fastembed/src/fastembed.ts","lineNumber":320,"sourceCode":"            reject(error);\n          });\n        })\n        .on('error', error => {\n          fs.unlink(outputFilePath, () => {\n            reject(error);\n          });\n        });\n    });\n  }\n\n  private static async decompressToCache(targzPath: PathLike, cacheDir: PathLike) {\n    if (path.extname(targzPath.toString()) === '.gz') {\n      await tar.x({\n        file: targzPath.toString(),\n        cwd: cacheDir.toString(),\n      });\n    } else {\n      throw new Error(`Unsupported file extension: ${targzPath}`);\n    }\n  }\n\n  static async retrieveModel(\n    model: EmbeddingModel,\n    cacheDir: PathLike,\n    showDownloadProgress: boolean = true,\n  ): Promise<PathLike> {\n    if (!fs.existsSync(cacheDir)) {\n      fs.mkdirSync(cacheDir, { mode: 0o755 });\n    }\n\n    const modelDir = path.join(cacheDir.toString(), model);\n\n    if (fs.existsSync(modelDir)) {\n      return modelDir;\n    }\n","sourceCodeStart":302,"sourceCodeEnd":338,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/fastembed/src/fastembed.ts#L302-L338","documentation":"decompressToCache() only knows how to extract files with the .gz extension (it pipes them through tar.x). If the downloaded model archive's path has any other extension, it assumes the archive format is unsupported and throws rather than guessing an extractor.","triggerScenarios":"Calling retrieveModel() (which calls decompressToCache) when the cached/downloaded archive path does not end in '.gz', e.g. a .tgz, .zip, or extensionless file in the cache dir.","commonSituations":"A CDN changed the archive format for a model; the user pre-seeded the cache with a differently-compressed archive; a partial/renamed download left a wrong extension; case mismatch like '.GZ' (path.extname comparison is case-sensitive).","solutions":["Check the actual file at the cache path and confirm it is a gzip/tar archive ending in '.gz'; re-download or rename it.","Clear the model cache directory so retrieveModel re-downloads the canonical .tar.gz archive.","If the source is genuinely .tgz or another format, convert it to a .gz tarball, or extend the extraction logic to handle that extension."],"exampleFix":"// before: cache contains model.tgz -> throws\n// after: rename/convert to .tar.gz\nconst { execSync } = require('child_process');\nexecSync(`gunzip -c model.tgz > model.tar.gz`);\nawait FastEmbed.retrieveModel(model, cacheDir); // now sees model.tar.gz","handlingStrategy":"validation","validationCode":"import { existsSync, statSync } from 'fs';\nfunction isGzipArchive(p) {\n  return typeof p === 'string' && existsSync(p) && p.toLowerCase().endsWith('.gz') && statSync(p).size > 0;\n}","typeGuard":"function isPathLikeWithGzExt(p) {\n  return typeof p === 'string' && p.toLowerCase().endsWith('.gz');\n}","tryCatchPattern":"try {\n  await FastEmbed.retrieveModel(model, cacheDir);\n} catch (e) {\n  if (String(e.message).startsWith('Unsupported file extension')) {\n    await redownloadModelToCache(model, cacheDir); // replace bad archive with canonical .tar.gz\n    return FastEmbed.retrieveModel(model, cacheDir);\n  }\n  throw e;\n}","preventionTips":["Always let retrieveModel download the archive itself rather than hand-seeding the cache.","Never rename or re-compress cached model archives.","Clear the cache dir after upgrading fastembed or changing model sources."],"tags":["filesystem","archive-extraction","cache"],"backgroundTag":"unsupported-archive-format","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T08:17:16.595Z"}