{"record":{"id":"12cceffe5a2bad3d","repo":"vercel/turborepo","slug":"package-manager-unexpected-12ccef","errorCode":"package_manager-unexpected","errorMessage":"Not a bun project","messagePattern":"Not a bun project","errorType":"exception","errorClass":"ConvertError","httpStatus":null,"severity":"error","filePath":"packages/turbo-workspaces/src/managers/bun.ts","lineNumber":58,"sourceCode":" */\n// eslint-disable-next-line @typescript-eslint/require-await -- must match the detect type signature\nasync function detect(args: DetectArgs): Promise<boolean> {\n  const lockFile = path.join(args.workspaceRoot, PACKAGE_MANAGER_DETAILS.lock);\n  const packageManager = getWorkspacePackageManager({\n    workspaceRoot: args.workspaceRoot\n  });\n  return (\n    fs.existsSync(lockFile) || packageManager === PACKAGE_MANAGER_DETAILS.name\n  );\n}\n\n/**\n  Read workspace data from bun workspaces into generic format\n*/\nasync function read(args: ReadArgs): Promise<Project> {\n  const isBun = await detect(args);\n  if (!isBun) {\n    throw new ConvertError(\"Not a bun project\", {\n      type: \"package_manager-unexpected\"\n    });\n  }\n\n  const packageJson = getPackageJson(args);\n  const { name, description } = getWorkspaceInfo(args);\n  const workspaceGlobs = parseWorkspacePackages({\n    workspaces: packageJson.workspaces\n  });\n  return {\n    name,\n    description,\n    packageManager: PACKAGE_MANAGER_DETAILS.name,\n    paths: expandPaths({\n      root: args.workspaceRoot,\n      lockFile: PACKAGE_MANAGER_DETAILS.lock\n    }),\n    workspaceData: {","sourceCodeStart":40,"sourceCodeEnd":76,"githubUrl":"https://github.com/vercel/turborepo/blob/9f94a7d215b3881942527dd526afa3fc650869d5/packages/turbo-workspaces/src/managers/bun.ts#L40-L76","documentation":"The bun manager's read() re-runs detect() (bun.lockb/bun.lock exists, or package.json declares bun) and throws ConvertError type package_manager-unexpected when the workspace is not a bun project. In the standard flow read() executes only after detect() passed, so this error indicates direct invocation or that workspace state changed between the two calls.","triggerScenarios":"Calling MANAGERS.bun.read({ workspaceRoot }) on a repo with no bun.lockb/bun.lock and no bun packageManager declaration; deleting the lockfile between detection and read.","commonSituations":"Direct API use in scripts or tests on non-bun fixtures; a stale Project/workspaceRoot captured before the user switched package managers.","solutions":["Use getWorkspaceDetails() so detection picks the right manager before read() runs","Guard direct calls with MANAGERS.bun.detect({ workspaceRoot }) and skip on false","If the project should be bun, restore bun.lock/bun.lockb or declare bun in package.json first"],"exampleFix":"// before\nconst project = await MANAGERS.bun.read({ workspaceRoot }); // no bun lockfile\n\n// after\nif (await MANAGERS.bun.detect({ workspaceRoot })) {\n  const project = await MANAGERS.bun.read({ workspaceRoot });\n} else {\n  throw new Error(`Expected a bun workspace at ${workspaceRoot}`);\n}","handlingStrategy":"validation","validationCode":"if (await MANAGERS.bun.detect({ workspaceRoot })) {\n  const project = await MANAGERS.bun.read({ workspaceRoot });\n} else {\n  throw new Error(`Refusing bun read: ${workspaceRoot} has no bun lockfile or declaration`);\n}","typeGuard":"function isUnexpectedManagerError(e: unknown): boolean {\n  return e instanceof ConvertError && e.type === \"package_manager-unexpected\";\n}","tryCatchPattern":"try {\n  const project = await MANAGERS.bun.read({ workspaceRoot });\n} catch (e) {\n  if (e instanceof ConvertError && e.type === \"package_manager-unexpected\") {\n    // workspace is not bun-managed; use getWorkspaceDetails() for generic detection\n  } else throw e;\n}","preventionTips":["Run detect() before read() when using manager internals directly","Use getWorkspaceDetails() for automatic manager selection","In tests, ensure bun fixtures contain a bun.lockb/bun.lock or a bun packageManager field"],"tags":["package-manager","detection","workspace","bun"],"backgroundTag":"package-manager-mismatch","analyzedSha":"9f94a7d215b3881942527dd526afa3fc650869d5","analyzedAt":"2026-08-16T19:47:29.531Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}