jackwener/OpenCLI · warning

Failed to transpile ${tsFile}: ${getErrorMessage(err)}

Error message

Failed to transpile ${tsFile}: ${getErrorMessage(err)}

What it means

The plugin loader transpiles plugin TypeScript files to JavaScript on the fly, shelling out to the TypeScript compiler (spawnSync with esbuild/tsc). If the transpile process fails to spawn or exits non-zero, this warning is logged and that file is skipped, leaving the plugin without the transpiled output (which may cause a later load failure for that plugin).

Source

Thrown at src/plugin.ts:1548

    );

    for (const tsFile of tsFiles) {
      const jsFile = tsFile.replace(/\.ts$/, '.js');
      const jsPath = path.join(pluginDir, jsFile);

      // Skip if .js already exists (plugin may ship pre-compiled)
      if (fs.existsSync(jsPath)) continue;

      try {
        execFileSync(esbuildBin, [tsFile, `--outfile=${jsFile}`, '--format=esm', '--platform=node'], {
          cwd: pluginDir,
          encoding: 'utf-8',
          stdio: ['pipe', 'pipe', 'pipe'],
          ...(isWindows && { shell: true }),
        });
        log.debug(`Transpiled plugin file: ${tsFile} → ${jsFile}`);
      } catch (err) {
        log.warn(`Failed to transpile ${tsFile}: ${getErrorMessage(err)}`);
      }
    }
  } catch (err) {
    log.warn(`TS transpilation setup failed: ${getErrorMessage(err)}`);
  }
}

export {
  resolveHostOpencliRoot as _resolveHostOpencliRoot,
  resolveEsbuildBin as _resolveEsbuildBin,
  getCommitHash as _getCommitHash,
  installDependencies as _installDependencies,
  parseSource as _parseSource,
  postInstallMonorepoLifecycle as _postInstallMonorepoLifecycle,
  readLockFile as _readLockFile,
  readLockFileWithWriter as _readLockFileWithWriter,
  updateAllPlugins as _updateAllPlugins,
  validatePluginStructure as _validatePluginStructure,

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Run the transpiler manually on the file (npx tsc <tsFile> or npx esbuild) to see the real compiler error.
  2. Install dev dependencies so the transpiler binary exists (npm install in the host/plugin project).
  3. Fix TypeScript errors in the plugin file reported by the compiler.
  4. Precompile the plugin to JS yourself and ship dist output so on-the-fly transpilation isn't needed.

Example fix

// before
// plugin ships only .ts, relies on runtime transpile
// after
npx tsc --outDir dist src/index.ts
// ship dist/index.js alongside or instead of src/index.ts
Defensive patterns

Strategy: fallback

Validate before calling

import { existsSync } from 'fs';
if (!existsSync('node_modules/.bin/tsc') && !existsSync('node_modules/.bin/esbuild')) {
  throw new Error('transpiler missing — run npm install');
}
// optionally: npx tsc --noEmit <tsFile> as a pre-check

Type guard

function hasTranspiler(binDir: string): boolean {
  return ['tsc', 'esbuild', 'tsc.cmd', 'esbuild.cmd'].some((b) => fs.existsSync(path.join(binDir, b)));
}

Try / catch

try {
  spawnSync(tscBin, [tsFile, '--outDir', outDir], { encoding: 'utf-8', stdio: 'pipe' });
} catch (err) {
  const msg = getErrorMessage(err);
  console.warn(`transpile failed for ${tsFile}: ${msg}`);
  if (fs.existsSync(prebuiltJs)) return prebuiltJs; // fall back to shipped dist output
}

Prevention

When it happens

Trigger: The child transpiler process throws or exits nonzero: tsc/esbuild binary not found (ENOENT on spawn), TypeScript syntax/type errors in tsFile, output directory not writable, or shell spawning issues on Windows.

Common situations: Node without devDependencies installed so tsc/esbuild is missing from node_modules/.bin; plugin TS code with type errors that tsc (not esbuild) rejects; read-only dist folder; Windows PATH quirks requiring shell:true (handled) but with a broken PATH.

Related errors


AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29). Data as JSON: /api/errors/5bc48f6adfda362c. Report an issue: GitHub.