chenglou/pretext · error · Error
Expected exactly one tarball in ${packDir}, found ${tarballs
Error message
Expected exactly one tarball in ${packDir}, found ${tarballs.length} What it means
packPackage() in package-smoke-test.ts runs `npm pack` into a temp directory, then asserts that exactly one `.tgz` was produced. It throws on zero or more than one. This protects the smoke test's assumption that the published artifact is a single tarball it can install.
Source
Thrown at scripts/package-smoke-test.ts:38
if (!keepTemp && succeeded) {
await rm(tempRoot, { recursive: true, force: true })
}
}
async function packPackage(): Promise<string> {
const packDir = path.join(tempRoot, 'pack')
await mkdir(packDir, { recursive: true })
run(['npm', 'pack', '--pack-destination', packDir], {
cwd: root,
stdout: 'inherit',
stderr: 'inherit',
})
const entries = await readdir(packDir)
const tarballs = entries.filter(entry => entry.endsWith('.tgz'))
if (tarballs.length !== 1) {
throw new Error(`Expected exactly one tarball in ${packDir}, found ${tarballs.length}`)
}
return path.join(packDir, tarballs[0]!)
}
async function smokeJavaScriptEsm(tarballPath: string): Promise<void> {
const projectDir = path.join(tempRoot, 'js-esm')
await createProject(projectDir, {
name: 'pretext-package-smoke-js-esm',
private: true,
type: 'module',
})
await installTarball(projectDir, tarballPath)
await writeFile(
path.join(projectDir, 'index.js'),
[
"import * as pretext from '@chenglou/pretext'",
"if (typeof pretext.prepare !== 'function') throw new Error('prepare export missing')",View on GitHub (pinned to ac49b09b7d)
Solutions
- Ensure `dist/` is built before packing (run the build step that emits dist/layout.js + dist/layout.d.ts).
- Run `npm pack` manually and inspect what it produces: `npm pack --dry-run` to see the file list.
- Confirm package.json has a single name and no nested package manifests that could cause double packing.
- Check the temp pack dir printed in the error for leftover `.tgz` artifacts.
Example fix
# before — dist not built, npm pack emits nothing bun run package-smoke-test # after bun run build # or whichever step emits dist/ bun run package-smoke-test
Defensive patterns
Strategy: validation
Validate before calling
import { readdir } from 'node:fs/promises'
async function expectSingleTarball(packDir: string): Promise<string> {
const tarballs = (await readdir(packDir)).filter(e => e.endsWith('.tgz'))
if (tarballs.length !== 1) {
console.error(`Expected 1 tarball, found ${tarballs.length}. Run \`npm pack --dry-run\` to inspect.`)
process.exit(1)
}
return tarballs[0]!
} Prevention
- Build dist/ before running the smoke test (published entrypoints target dist/layout.js).
- Run `npm pack --dry-run` first to confirm the file list and that exactly one tarball is produced.
When it happens
Trigger: Zero tarballs: `npm pack` wrote nothing (e.g. package not buildable, dist/ missing on a clean checkout). More than one: package.json defines multiple packages or a prior pack left stale `.tgz` files in the pack dir (shouldn't happen since packDir is freshly made, but a misconfigured `files`/`prepack` could).
Common situations: Running the smoke test without building dist/ first (the published entrypoints target dist/layout.js), or running it in a worktree with an unusual package layout.
Related errors
- Command failed (${result.exitCode}): ${cmd.join(' ')}
- Expected TypeScript consumer misuse to fail, but it compiled
- Unexpected TypeScript consumer error output: ${combinedOutpu
AI-assisted analysis of chenglou/pretext@ac49b09b7d (2026-08-12).
Data as JSON: /api/errors/12638ed3a004d1f9.
Report an issue: GitHub.