{"record":{"id":"ea87eb3492a92cbc","repo":"vercel/turborepo","slug":"bun-workspace-glob-error","errorCode":"bun-workspace_glob_error","errorMessage":"Unable to convert project to bun - workspace globs unsupported","messagePattern":"Unable to convert project to bun - workspace globs unsupported","errorType":"exception","errorClass":"ConvertError","httpStatus":null,"severity":"error","filePath":"packages/turbo-workspaces/src/managers/bun.ts","lineNumber":101,"sourceCode":"  };\n}\n\n/**\n * Create bun workspaces from generic format\n *\n * Creating bun workspaces involves:\n *  1. Validating that the project can be converted to bun workspace\n *  2. Adding the workspaces field in package.json\n *  3. Setting the devEngines.packageManager field in package.json\n *  4. Updating all workspace package.json dependencies to ensure correct format\n */\n// eslint-disable-next-line @typescript-eslint/require-await -- must match the create type signature\nasync function create(args: CreateArgs): Promise<void> {\n  const { project, to, logger, options } = args;\n  const hasWorkspaces = project.workspaceData.globs.length > 0;\n\n  if (!isCompatibleWithBunWorkspaces({ project })) {\n    throw new ConvertError(\n      \"Unable to convert project to bun - workspace globs unsupported\",\n      {\n        type: \"bun-workspace_glob_error\"\n      }\n    );\n  }\n\n  logger.mainStep(\n    getMainStep({\n      packageManager: PACKAGE_MANAGER_DETAILS.name,\n      action: \"create\",\n      project\n    })\n  );\n  const packageJson = getPackageJson({ workspaceRoot: project.paths.root });\n  logger.rootHeader();\n\n  // package manager","sourceCodeStart":83,"sourceCodeEnd":119,"githubUrl":"https://github.com/vercel/turborepo/blob/9f94a7d215b3881942527dd526afa3fc650869d5/packages/turbo-workspaces/src/managers/bun.ts#L83-L119","documentation":"The bun manager's create() validates the project's workspace globs with isCompatibleWithBunWorkspaces(), which mirrors bun's own lockfile glob rules: no '**' recursive segments, '*' only in the final path segment, and none of the characters '!', '[', ']', '{', '}'. If any glob violates a rule, conversion aborts with ConvertError type bun-workspace_glob_error before files are written. Turborepo deliberately will not rewrite globs to make a project fit.","triggerScenarios":"Converting to bun a workspace whose globs include 'packages/**', 'apps/*/lib', 'packages/{a,b}', or '!excluded-pkg' — patterns legal in pnpm/yarn workspaces but rejected by bun's implementation.","commonSituations":"pnpm-workspace.yaml with recursive globs for nested packages; monorepos using brace expansion or negation; yarn workspaces arrays with multiple levels.","solutions":["Restructure globs so '*' appears only in the last segment: 'packages/*' instead of 'packages/**'","Remove brace expansion ('{a,b}') and negation ('!pkg') patterns; enumerate members explicitly or relocate excluded packages","If restructuring is impossible, convert manually: write a bun-compatible workspaces field and devEngines.packageManager yourself"],"exampleFix":"// before (pnpm-workspace.yaml)\npackages:\n  - 'packages/**'\n  - '!packages/**/dist'\n\n// after (bun-compatible)\npackages:\n  - 'apps/*'\n  - 'packages/*'","handlingStrategy":"validation","validationCode":"function isBunCompatibleGlob(glob: string): boolean {\n  if (glob.includes(\"*\")) {\n    if (glob.includes(\"**\")) return false;\n    const beforeLastSegment = glob.split(\"/\").slice(0, -1).join(\"/\");\n    if (beforeLastSegment.includes(\"*\")) return false;\n  }\n  return ![\"!\", \"[\", \"]\", \"{\", \"}\"].some((c) => glob.includes(c));\n}\n\nconst incompatible = project.workspaceData.globs.filter((g) => !isBunCompatibleGlob(g));\nif (incompatible.length) {\n  throw new Error(`Fix globs before bun conversion: ${incompatible.join(\", \")}`);\n}","typeGuard":"function isBunGlobError(e: unknown): boolean {\n  return e instanceof ConvertError && e.type === \"bun-workspace_glob_error\";\n}","tryCatchPattern":"try {\n  await convertProject({ project, convertTo: bunDetails, logger });\n} catch (e) {\n  if (e instanceof ConvertError && e.type === \"bun-workspace_glob_error\") {\n    // flatten globs (packages/** -> packages/*) or enumerate workspaces explicitly, then retry\n  } else throw e;\n}","preventionTips":["Keep workspace globs simple ('apps/*', 'packages/*') so they stay portable across managers","Avoid '**', brace expansion, and negation in workspace definitions","Pre-validate globs against bun's rules before offering bun as a conversion target"],"tags":["package-manager","bun","globs","conversion","workspaces"],"backgroundTag":"unsupported-workspace-glob","analyzedSha":"9f94a7d215b3881942527dd526afa3fc650869d5","analyzedAt":"2026-08-16T19:47:29.531Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}