{"record":{"id":"1130f8ce741b085e","repo":"paperclipai/paperclip","slug":"entrypoint-name-bundle-retained-a-non-builtin-i","errorCode":null,"errorMessage":"${entrypoint.name} bundle retained a non-builtin import: ${dependency.path}","messagePattern":"(.+?) bundle retained a non-builtin import: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/paperclip-runner/scripts/build-verified-provider-entrypoints.mjs","lineNumber":45,"sourceCode":"\nconst nodeBuiltins = new Set([\n  ...builtinModules,\n  ...builtinModules.map((name) => `node:${name}`),\n]);\n\nfunction assertSelfContainedBundle(entrypoint, result) {\n  const outputs = Object.entries(result.metafile.outputs).filter(\n    ([, output]) => output.entryPoint !== undefined,\n  );\n  if (outputs.length !== 1) {\n    throw new Error(\n      `${entrypoint.name} bundle emitted ${outputs.length} entrypoint outputs instead of one`,\n    );\n  }\n  const imports = outputs[0][1].imports;\n  for (const dependency of imports) {\n    if (!dependency.external || !nodeBuiltins.has(dependency.path)) {\n      throw new Error(\n        `${entrypoint.name} bundle retained a non-builtin import: ${dependency.path}`,\n      );\n    }\n  }\n}\n\nexport async function bundleVerifiedProviderEntrypoints({ write = true } = {}) {\n  const results = [];\n  for (const entrypoint of verifiedProviderEntrypoints) {\n    const buildBundle = async (outfile, format) => {\n      const result = await build({\n        entryPoints: [entrypoint.source],\n        outfile,\n        bundle: true,\n        platform: \"node\",\n        format,\n        target: \"node24\",\n        packages: \"bundle\",","sourceCodeStart":27,"sourceCodeEnd":63,"githubUrl":"https://github.com/paperclipai/paperclip/blob/01ad8584922b5d85292b1723cae71fa0d9b07a19/packages/paperclip-runner/scripts/build-verified-provider-entrypoints.mjs#L27-L63","documentation":"The verified-provider entrypoint build asserts that each bundled entrypoint output is fully self-contained: every remaining import must be an externalized Node builtin. If esbuild emits an import that is neither external nor in the nodeBuiltins allowlist, the build is considered unsafe and this error is thrown.","triggerScenarios":"Running the build-verified-provider-entrypoints script when a provider entrypoint imports a package that esbuild left as an external runtime import (marked external or unresolved) but that is not a Node builtin, so outputs[0].imports contains a non-builtin dependency.","commonSituations":"A new provider adapter adds an import to a dependency the bundler externalizes by mistake; a package uses a dynamic require that esbuild leaves external; the esbuild 'external' option was misconfigured.","solutions":["Inspect dependency.path in the error to identify the offending import and remove or bundle it (make esbuild inline it instead of leaving it external).","Check the esbuild configuration in the script for an 'external' entry covering that package and remove it so it gets inlined.","If the import genuinely must stay external, verify it is a Node builtin (prefer node: prefix) so it matches the nodeBuiltins allowlist.","Re-run the script after fixing to confirm the single entrypoint output has only builtin imports."],"exampleFix":"// before (esbuild config)\nbuild({ entryPoints: ['src/provider.ts'], external: ['some-helper-pkg'], bundle: true });\n// after\nbuild({ entryPoints: ['src/provider.ts'], bundle: true }); // some-helper-pkg now inlined","handlingStrategy":"validation","validationCode":"// Pre-check the bundle imports before asserting\nimport { analyzeMetafile } from 'esbuild';\nconst meta = JSON.parse(await analyzeMetafile(result, { verbose: false }));\nconst bad = meta.outputs.flatMap(o => o.imports).filter(i => !i.external || !(i.external.startsWith?.('node:') || BUILTINS.includes(i.external)));\nif (bad.length) console.error('Non-builtin imports:', bad.map(b => b.path).join(', '));","typeGuard":"function isNodeBuiltinImport(dep) {\n  return dep.external && (dep.path.startsWith('node:') || ['fs','path','crypto','child_process','url','util'].includes(dep.path));\n}","tryCatchPattern":"try {\n  await buildVerifiedEntrypoints();\n} catch (err) {\n  if (String(err.message).includes('retained a non-builtin import')) {\n    console.error('Bundle config leak:', err.message);\n  }\n  throw err;\n}","preventionTips":["Never add runtime packages to the esbuild 'external' list for these entrypoints.","Keep nodeBuiltins derived from the node: prefix check rather than a hand-maintained list.","Run the verified build in CI on every provider change.","Grep new provider code for imports of packages that should be bundled before merging."],"tags":["build","bundler","esbuild","security"],"backgroundTag":"invalid-config-value","analyzedSha":"01ad8584922b5d85292b1723cae71fa0d9b07a19","analyzedAt":"2026-09-10T03:14:50.855Z","contentChangedAt":"2026-09-10T03:14:50.855Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}