pbakaus/impeccable · error

Cannot build OpenAI plugin: missing ${label}: ${absPath}

Error message

Cannot build OpenAI plugin: missing ${label}: ${absPath}

What it means

Thrown by stageOpenAIPlugin() when one of three required inputs is missing on disk: the root .claude-plugin/plugin.json manifest, the Codex-transformed skill payload under dist/codex/.codex/skills/impeccable, or the plugin icon at scripts/lib/assets/plugin-icon.png. The build cannot assemble an OpenAI/Codex plugin without all three.

Source

Thrown at scripts/lib/openai-plugin.js:9

import fs from 'fs';
import path from 'path';

import { buildCodexPluginManifest } from './codex-plugin.js';
import { buildCodexPluginHooksManifest } from './transformers/hooks.js';

function requirePath(absPath, label) {
  if (!fs.existsSync(absPath)) {
    throw new Error(`Cannot build OpenAI plugin: missing ${label}: ${absPath}`);
  }
}

function writeJson(absPath, value) {
  fs.mkdirSync(path.dirname(absPath), { recursive: true });
  fs.writeFileSync(absPath, `${JSON.stringify(value, null, 2)}\n`);
}

/**
 * Stage the public OpenAI plugin from the Codex-transformed skill payload.
 *
 * The tracked ./plugin subtree is a Claude Code marketplace artifact. Reusing
 * its shared skills/ directory here silently ships Claude paths and slash
 * commands inside a Codex plugin. Keep this stage independent so each plugin
 * receives the provider transform it was built for.
 */
export function stageOpenAIPlugin(rootDir, distDir) {
  const rootManifestPath = path.join(rootDir, '.claude-plugin', 'plugin.json');

View on GitHub (pinned to d14711ae3d)

Solutions

  1. Run the full `bun run build:release` (or at least the Codex transform step) before the OpenAI stage so dist/codex/.codex/skills/impeccable exists.
  2. Confirm the printed absPath for the missing label exists; create or restore it.
  3. Restore .claude-plugin/plugin.json and scripts/lib/assets/plugin-icon.png from git if they were deleted.

Example fix

// before — running stageOpenAIPlugin before the Codex stage
stageOpenAIPlugin(rootDir, distDir);

// after — ensure the Codex payload is built first
await buildCodexSkillPayload(rootDir, distDir);
stageOpenAIPlugin(rootDir, distDir);
Defensive patterns

Strategy: validation

Validate before calling

import { existsSync } from 'node:fs';
const required = [
  ['.claude-plugin/plugin.json', 'root plugin manifest'],
  [path.join(distDir, 'codex', '.codex', 'skills', 'impeccable'), 'Codex skill payload'],
  ['scripts/lib/assets/plugin-icon.png', 'plugin icon'],
];
for (const [p, label] of required) {
  if (!existsSync(path.join(rootDir, p))) console.error(`Missing ${label}: ${p}`);
}

Type guard

function openAiPluginInputsReady(rootDir, distDir) {
  return existsSync(path.join(rootDir, '.claude-plugin', 'plugin.json'))
    && existsSync(path.join(distDir, 'codex', '.codex', 'skills', 'impeccable'))
    && existsSync(path.join(rootDir, 'scripts', 'lib', 'assets', 'plugin-icon.png'));
}

Try / catch

try {
  stageOpenAIPlugin(rootDir, distDir);
} catch (err) {
  if (/Cannot build OpenAI plugin: missing/.test(err.message)) {
    console.error('OpenAI stage inputs missing; run the Codex transform stage first.');
  } else throw err;
}

Prevention

When it happens

Trigger: Running the OpenAI plugin stage before the Codex transform stage has produced dist/codex/...; deleting or moving the plugin icon asset; running from a shallow clone that omitted .claude-plugin/plugin.json; a partial build that ran stageOpenAIPlugin out of order.

Common situations: CI job that runs the OpenAI stage without first running the Codex transformer; a contributor removed scripts/lib/assets/plugin-icon.png; the manifest was relocated during a repo restructure.

Related errors


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