Hmbown/CodeWhale · error · Error
CODEWHALE_SMOKE_ASSETS_DIR is not a directory: ${releaseAsse
Error message
CODEWHALE_SMOKE_ASSETS_DIR is not a directory: ${releaseAssetsDir} What it means
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.
Source
Thrown at scripts/release/npm-wrapper-smoke.js:155
const suppliedAssetsDir = String(
process.env.CODEWHALE_SMOKE_ASSETS_DIR || "",
).trim();
const releaseAssetsDir = suppliedAssetsDir
? path.resolve(suppliedAssetsDir)
: path.join(tempRoot, "release-assets");
const packDir = path.join(tempRoot, "pack");
const installDir = path.join(tempRoot, "install");
let keepTemp = process.env.DEEPSEEK_TUI_KEEP_SMOKE_DIR === "1";
let server;
try {
await fsp.mkdir(packDir, { recursive: true });
await fsp.mkdir(installDir, { recursive: true });
if (suppliedAssetsDir) {
const assetDirectoryStat = await fsp.stat(releaseAssetsDir);
if (!assetDirectoryStat.isDirectory()) {
throw new Error(`CODEWHALE_SMOKE_ASSETS_DIR is not a directory: ${releaseAssetsDir}`);
}
console.log(`Using preassembled release assets from ${releaseAssetsDir}`);
} else {
const prepareArgs = [prepareAssetsScript, releaseAssetsDir];
const cargoTargetDir = String(process.env.CARGO_TARGET_DIR || "").trim();
if (cargoTargetDir) {
prepareArgs.push(
path.join(path.resolve(repoRoot, cargoTargetDir), "release"),
);
}
await runCommand(process.execPath, prepareArgs);
}
const served = await serveDirectory(releaseAssetsDir);
server = served.server;
const env = {
DEEPSEEK_TUI_FORCE_DOWNLOAD: "1",
DEEPSEEK_TUI_RELEASE_BASE_URL: served.baseUrl,View on GitHub (pinned to 8880682c63)
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
Example fix
# before CODEWHALE_SMOKE_ASSETS_DIR=dist/codewhale-x86_64-unknown-linux-gnu.tar.gz node scripts/release/npm-wrapper-smoke.js # after mkdir -p /tmp/assets && tar -xzf dist/codewhale-x86_64-unknown-linux-gnu.tar.gz -C /tmp/assets CODEWHALE_SMOKE_ASSETS_DIR=/tmp/assets node scripts/release/npm-wrapper-smoke.js
Defensive patterns
Strategy: validation
Validate before calling
import { statSync } from 'node:fs';
const dir = process.env.CODEWHALE_SMOKE_ASSETS_DIR;
if (dir && !statSync(dir).isDirectory()) {
throw new Error(`CODEWHALE_SMOKE_ASSETS_DIR is not a directory: ${dir}`);
} Prevention
- 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
When it happens
Trigger: Setting CODEWHALE_SMOKE_ASSETS_DIR to a .tar.gz/.zip artifact instead of its extracted directory, or to any regular file.
Common situations: CI passing the artifact file path from a previous job step; copying the env var from a context where only the archive exists.
Related errors
- Release asset directory must be flat; found: ${nonFiles.map(
- Downloaded release artifacts are missing ${name} at ${source
- Downloaded release artifact must be a regular file: ${source
- Output directory must be empty: ${outputDirectory}
- ${label} does not match the authoritative inventory; missing
AI-assisted analysis of Hmbown/CodeWhale@8880682c63 (2026-08-16).
Data as JSON: /api/errors/5fd424e36dd332c4.
Report an issue: GitHub.