{"record":{"id":"5fd424e36dd332c4","repo":"Hmbown/CodeWhale","slug":"codewhale-smoke-assets-dir-is-not-a-directory-r","errorCode":null,"errorMessage":"CODEWHALE_SMOKE_ASSETS_DIR is not a directory: ${releaseAssetsDir}","messagePattern":"CODEWHALE_SMOKE_ASSETS_DIR is not a directory: (.+?)","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"scripts/release/npm-wrapper-smoke.js","lineNumber":155,"sourceCode":"  const suppliedAssetsDir = String(\n    process.env.CODEWHALE_SMOKE_ASSETS_DIR || \"\",\n  ).trim();\n  const releaseAssetsDir = suppliedAssetsDir\n    ? path.resolve(suppliedAssetsDir)\n    : path.join(tempRoot, \"release-assets\");\n  const packDir = path.join(tempRoot, \"pack\");\n  const installDir = path.join(tempRoot, \"install\");\n  let keepTemp = process.env.DEEPSEEK_TUI_KEEP_SMOKE_DIR === \"1\";\n  let server;\n\n  try {\n    await fsp.mkdir(packDir, { recursive: true });\n    await fsp.mkdir(installDir, { recursive: true });\n\n    if (suppliedAssetsDir) {\n      const assetDirectoryStat = await fsp.stat(releaseAssetsDir);\n      if (!assetDirectoryStat.isDirectory()) {\n        throw new Error(`CODEWHALE_SMOKE_ASSETS_DIR is not a directory: ${releaseAssetsDir}`);\n      }\n      console.log(`Using preassembled release assets from ${releaseAssetsDir}`);\n    } else {\n      const prepareArgs = [prepareAssetsScript, releaseAssetsDir];\n      const cargoTargetDir = String(process.env.CARGO_TARGET_DIR || \"\").trim();\n      if (cargoTargetDir) {\n        prepareArgs.push(\n          path.join(path.resolve(repoRoot, cargoTargetDir), \"release\"),\n        );\n      }\n      await runCommand(process.execPath, prepareArgs);\n    }\n    const served = await serveDirectory(releaseAssetsDir);\n    server = served.server;\n\n    const env = {\n      DEEPSEEK_TUI_FORCE_DOWNLOAD: \"1\",\n      DEEPSEEK_TUI_RELEASE_BASE_URL: served.baseUrl,","sourceCodeStart":137,"sourceCodeEnd":173,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/8880682c63083a91624de936797efa3ce9e498fd/scripts/release/npm-wrapper-smoke.js#L137-L173","documentation":"The smoke test was pointed at preassembled release assets via CODEWHALE_SMOKE_ASSETS_DIR; fsp.stat() resolved the path but it is not a directory (a regular file or a symlink to a file, such as a packaged asset archive). Note: a nonexistent path fails earlier at stat() with ENOENT, not this error.","triggerScenarios":"Setting CODEWHALE_SMOKE_ASSETS_DIR to a .tar.gz/.zip artifact instead of its extracted directory, or to any regular file.","commonSituations":"CI passing the artifact file path from a previous job step; copying the env var from a context where only the archive exists.","solutions":["Point CODEWHALE_SMOKE_ASSETS_DIR at the extracted directory (the output of the prepare-release-assets script)","Unset the variable so the smoke test assembles the assets itself into its temp dir","Extract first: `mkdir -p /tmp/assets && tar -xzf <archive> -C /tmp/assets`, then pass /tmp/assets"],"exampleFix":"# before\nCODEWHALE_SMOKE_ASSETS_DIR=dist/codewhale-x86_64-unknown-linux-gnu.tar.gz node scripts/release/npm-wrapper-smoke.js\n\n# after\nmkdir -p /tmp/assets && tar -xzf dist/codewhale-x86_64-unknown-linux-gnu.tar.gz -C /tmp/assets\nCODEWHALE_SMOKE_ASSETS_DIR=/tmp/assets node scripts/release/npm-wrapper-smoke.js","handlingStrategy":"validation","validationCode":"import { statSync } from 'node:fs';\nconst dir = process.env.CODEWHALE_SMOKE_ASSETS_DIR;\nif (dir && !statSync(dir).isDirectory()) {\n  throw new Error(`CODEWHALE_SMOKE_ASSETS_DIR is not a directory: ${dir}`);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Pass the extracted assets directory, never the archive file","In CI, add an extraction step that materializes the directory before the smoke run","Unset the variable when you want the script to build assets itself"],"tags":["ci","release","config","filesystem"],"backgroundTag":null,"analyzedSha":"8880682c63083a91624de936797efa3ce9e498fd","analyzedAt":"2026-08-16T11:31:27.956Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}