pbakaus/impeccable · error

Cannot create ${zipFileName}: provider directory not found:

Error message

Cannot create ${zipFileName}: provider directory not found: ${providerDir}

What it means

Thrown by createProviderZip() when the provider source directory does not exist on disk before archiving. The zip is an install artifact consumed by `npx impeccable skills install`, so the build refuses to produce a bundle from a missing source rather than ship a broken package.

Source

Thrown at scripts/lib/zip.js:25

 */

import path from 'path';
import { createWriteStream, existsSync, statSync } from 'fs';
// archiver v8 is ESM and exports format-specific classes (no factory function).
import { ZipArchive } from 'archiver';

/**
 * Create ZIP file for a provider directory
 * @param {string} providerDir - Path to provider directory
 * @param {string} distDir - Path to dist directory
 * @param {string} providerName - Name of the provider
 */
export async function createProviderZip(providerDir, distDir, providerName) {
  const zipFileName = `${providerName}.zip`;
  const zipPath = path.join(distDir, zipFileName);

  if (!existsSync(providerDir)) {
    throw new Error(`Cannot create ${zipFileName}: provider directory not found: ${providerDir}`);
  }

  // Fail loud, never soft. This artifact ships to `npx impeccable skills
  // install` via the bundle endpoint; a build that can't produce a real zip
  // must exit non-zero rather than deploy an empty one. (archiver v8's ESM
  // break previously failed here silently and shipped a 0-byte universal.zip.)
  let entryCount = 0;
  await new Promise((resolve, reject) => {
    const output = createWriteStream(zipPath);
    const archive = new ZipArchive({ zlib: { level: 9 } });

    output.on('close', resolve);
    output.on('error', reject);
    archive.on('error', reject);
    archive.on('entry', () => { entryCount += 1; });

    archive.pipe(output);
    archive.glob('**/*', {

View on GitHub (pinned to d14711ae3d)

Solutions

  1. Ensure the provider stage that populates providerDir (e.g. the universal stage writing dist/universal) runs before createProviderZip.
  2. Verify the printed providerDir path exists with `ls`; fix the path or generate the directory.
  3. Run `bun run build` which orders the stages correctly.

Example fix

// before
await createProviderZip(path.join(distDir, 'universal'), distDir, 'universal');
// but distDir/universal was never created

// after — ensure the universal stage runs first
await stageUniversalProvider(distDir);
await createProviderZip(path.join(distDir, 'universal'), distDir, 'universal');
Defensive patterns

Strategy: validation

Validate before calling

import { existsSync } from 'node:fs';
if (!existsSync(providerDir)) {
  throw new Error(`Stage the provider directory first: ${providerDir}`);
}

Type guard

function providerDirReady(providerDir) {
  return existsSync(providerDir);
}

Try / catch

try {
  await createProviderZip(providerDir, distDir, providerName);
} catch (err) {
  if (/provider directory not found/.test(err.message)) {
    console.error('Run the provider stage before zipping:', providerDir);
  } else throw err;
}

Prevention

When it happens

Trigger: Calling createProviderZip with a providerDir path that does not exist — typically dist/universal missing because the universal provider stage never ran; passing a provider name whose stage was skipped in the build pipeline.

Common situations: A custom build script calls createProviderZip before the universal directory is generated; a refactor renamed the provider output directory but not the createAllZips caller; CI that pruned empty dist subdirs.

Related errors


AI-assisted analysis of pbakaus/impeccable@d14711ae3d (2026-08-13). Data as JSON: /api/errors/bc18ef63471f7b24. Report an issue: GitHub.