EveryInc/compound-engineering-plugin · error · Error

Target ${targetName} did not return a bundle.

Error message

Target ${targetName} did not return a bundle.

What it means

After the target handler passes the implemented check, `install` calls `target.convert(plugin, options)`. A handler may return null (the TargetHandler type allows `TBundle | null`) when conversion cannot produce a bundle — for example when the plugin has nothing convertible for that target. The command throws this error because a null bundle means there is nothing to write.

Source

Thrown at src/commands/install.ts:168

        if (activeTargets.some((t) => t.name === "codex")) {
          await stripCodexAgentsToolMap(codexHome)
        }
        return
      }

      const target = targets[targetName]
      if (!target) {
        throw new Error(`Unknown target: ${targetName}`)
      }
      if (!target.implemented) {
        throw new Error(`Target ${targetName} is registered but not implemented yet.`)
      }

      const resolvedScope = validateScope(targetName, target, args.scope ? String(args.scope) : undefined)

      const bundle = target.convert(plugin, options)
      if (!bundle) {
        throw new Error(`Target ${targetName} did not return a bundle.`)
      }
      const primaryOutputRoot = resolveTargetOutputRoot({
        targetName,
        outputRoot,
        codexHome,
        piHome,
        pluginName: plugin.manifest.name,
        hasExplicitOutput,
        scope: resolvedScope,
      })
      const effectiveScope =
        targetName === "opencode" ? resolveOpenCodeWriteScope(hasExplicitOutput, resolvedScope) : resolvedScope
      await target.write(primaryOutputRoot, bundle, effectiveScope)
      console.log(`Installed ${plugin.manifest.name} to ${primaryOutputRoot}`)

      const extraTargets = parseExtraTargets(args.also)
      const allTargets = [targetName, ...extraTargets]
      for (const extra of extraTargets) {

View on GitHub (pinned to c9c10f8c75)

Solutions

  1. Inspect the plugin source: confirm it contains content the target can convert (agents, skills, commands, etc.).
  2. Try a different --to target (e.g. opencode) to see whether the plugin converts at all.
  3. If writing a custom target handler, return an empty-but-valid bundle instead of null, or document that null means 'nothing to install'.
  4. Update the CLI/converter if a recent change made conversion return null for a previously-convertible plugin.

Example fix

// before (custom handler)
convert: (plugin) => plugin.agents.length ? convert(plugin) : null
// after
convert: (plugin) => convert(plugin) // always produce a bundle; writer skips empty sections
Defensive patterns

Strategy: try-catch

Try / catch

try {
  await install(plugin, { to: target })
} catch (e) {
  if (e instanceof Error && e.message.includes("did not return a bundle")) {
    console.error(`Plugin has nothing convertible for ${target}; check its agents/skills or try --to opencode`)
  } else throw e
}

Prevention

When it happens

Trigger: Calling `install` against a target whose convert() returns null for the given plugin — e.g. a converter that bails on a plugin with no agents/skills of the kind it maps, or a bug in a custom converter returning null instead of a valid bundle.

Common situations: Installing a minimal or empty plugin (no convertible content) into a target whose converter yields null; developing a new target writer whose convert step returns null on edge cases; converter regression after a parser change.

Related errors


AI-assisted analysis of EveryInc/compound-engineering-plugin@c9c10f8c75 (2026-08-31). Data as JSON: /api/errors/84886d647ac1344a. Report an issue: GitHub.