{"record":{"id":"f0377a225e62db2a","repo":"EveryInc/compound-engineering-plugin","slug":"target-targetname-did-not-return-a-bundle","errorCode":null,"errorMessage":"Target ${targetName} did not return a bundle.","messagePattern":"Target (.+?) did not return a bundle\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/commands/convert.ts","lineNumber":167,"sourceCode":"\n    if (!target.implemented) {\n      throw new Error(`Target ${targetName} is registered but not implemented yet.`)\n    }\n\n    const resolvedScope = validateScope(targetName, target, args.scope ? String(args.scope) : undefined)\n\n    const primaryOutputRoot = resolveTargetOutputRoot({\n      targetName,\n      outputRoot,\n      codexHome,\n      piHome,\n      pluginName: plugin.manifest.name,\n      hasExplicitOutput,\n      scope: resolvedScope,\n    })\n    const bundle = target.convert(plugin, options)\n    if (!bundle) {\n      throw new Error(`Target ${targetName} did not return a bundle.`)\n    }\n\n    const effectiveScope =\n      targetName === \"opencode\" ? resolveOpenCodeWriteScope(hasExplicitOutput, resolvedScope) : resolvedScope\n    await target.write(primaryOutputRoot, bundle, effectiveScope)\n    console.log(`Converted ${plugin.manifest.name} to ${targetName} at ${primaryOutputRoot}`)\n\n    const extraTargets = parseExtraTargets(args.also)\n    const allTargets = [targetName, ...extraTargets]\n    for (const extra of extraTargets) {\n      const handler = targets[extra]\n      if (!handler) {\n        console.warn(`Skipping unknown target: ${extra}`)\n        continue\n      }\n      if (!handler.implemented) {\n        console.warn(`Skipping ${extra}: not implemented yet.`)\n        continue","sourceCodeStart":149,"sourceCodeEnd":185,"githubUrl":"https://github.com/EveryInc/compound-engineering-plugin/blob/c9c10f8c75412c7232cb2bd663e5fd1cea98d84e/src/commands/convert.ts#L149-L185","documentation":"After resolving the output root and scope, `run` calls `target.convert(plugin, options)` and expects a bundle object describing the converted output. A defensive check throws this error if the handler returns null/undefined. This is an internal contract failure — with the shipped converters it essentially never fires; it indicates a broken or partially-written target handler returning no bundle.","triggerScenarios":"A custom or in-development target handler whose `convert` returns undefined/null (e.g. an early-return on an unhandled plugin shape, or a stub that returns nothing), then running convert against that target.","commonSituations":"Contributors adding a new target provider per the checklist whose convert implementation isn't finished; monkey-patching or wrapping a target handler in a script; a plugin manifest so malformed that the converter bails with a null return instead of throwing.","solutions":["Inspect the target's `convert` handler (src/targets/*.ts) and ensure it returns a bundle for all valid plugin inputs.","Verify the source plugin loaded correctly (valid .claude-plugin/plugin.json, skills, etc.) — a converter may return null on unexpected input.","If this fires on a stock target with an unmodified plugin, report it as a bug; it indicates a broken converter contract."],"exampleFix":"// before (in a custom target handler)\nconvert: (plugin, options) => {\n  if (plugin.manifest.name === \"x\") return\n  ...\n}\n// after\nconvert: (plugin, options) => {\n  if (plugin.manifest.name === \"x\") return buildEmptyBundle(plugin)\n  ...\n}","handlingStrategy":"try-catch","validationCode":"import { targets } from \"./src/targets/index\"\nconst handler = targets[targetName]\nif (handler) {\n  const bundle = handler.convert(plugin, options)\n  if (!bundle) throw new Error(`${targetName}.convert returned no bundle for plugin ${plugin.manifest.name}`)\n}","typeGuard":"function isBundle(b: unknown): b is NonNullable<ReturnType<TargetHandler[\"convert\"]>> {\n  return typeof b === \"object\" && b !== null\n}","tryCatchPattern":"try {\n  await convert({ to: targetName, source })\n} catch (e) {\n  if (e instanceof Error && e.message.includes(\"did not return a bundle\")) {\n    console.error(`Converter bug in '${targetName}': inspect its convert() handler; check the source plugin shape.`)\n  } else throw e\n}","preventionTips":["When authoring a target handler, make convert() return a bundle on every code path; throw on unsupported input instead of returning null.","Add a unit test asserting convert() is non-null for the sample plugin fixture.","Don't wrap handlers in wrappers that can drop the return value."],"tags":["cli","internal-contract","converters"],"backgroundTag":"null-contract-violation","analyzedSha":"c9c10f8c75412c7232cb2bd663e5fd1cea98d84e","analyzedAt":"2026-08-31T15:18:07.959Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}