vercel/turborepo · error · ConvertError
package_manager-unexpected
package_manager-unexpected
Error message
Not an aube project
What it means
The aube manager's read() is a guarded internal step: it re-runs detect() (which checks the workspace's declared manager equals 'aube') and throws ConvertError type package_manager-unexpected if detection fails. In the normal getWorkspaceDetails() flow read() runs only after detect() succeeded, so hitting this means read() was invoked directly or workspace state changed between the calls.
Source
Thrown at packages/turbo-workspaces/src/managers/aube.ts:58
const UNDERLYING_MANAGERS = {
npm,
pnpm,
yarn,
bun
} as const;
// eslint-disable-next-line @typescript-eslint/require-await -- must match the detect type signature
async function detect(args: DetectArgs): Promise<boolean> {
return (
getWorkspacePackageManager({ workspaceRoot: args.workspaceRoot }) ===
PACKAGE_MANAGER_DETAILS.name
);
}
async function read(args: ReadArgs): Promise<Project> {
if (!(await detect(args))) {
throw new ConvertError("Not an aube project", {
type: "package_manager-unexpected"
});
}
const underlying = getUnderlyingLockfileManager({
workspaceRoot: args.workspaceRoot
});
const underlyingHandler = UNDERLYING_MANAGERS[underlying];
if (await underlyingHandler.detect(args)) {
const project = await underlyingHandler.read(args);
return { ...project, packageManager: PACKAGE_MANAGER_DETAILS.name };
}
const packageJson = getPackageJson(args);
const { name, description } = getWorkspaceInfo(args);
const lockfile = getUnderlyingLockfileName({
workspaceRoot: args.workspaceRootView on GitHub (pinned to 9f94a7d215)
Solutions
- Use getWorkspaceDetails() instead of calling a manager's read() directly — it runs detect() first and only reads the matching manager
- If calling read() directly, run MANAGERS.aube.detect({ workspaceRoot }) first and bail on false
- Ensure the project genuinely declares aube (devEngines.packageManager/packageManager) and has its lockfile
Example fix
// before
const project = await MANAGERS.aube.read({ workspaceRoot }); // not an aube repo
// after
if (await MANAGERS.aube.detect({ workspaceRoot })) {
const project = await MANAGERS.aube.read({ workspaceRoot });
} Defensive patterns
Strategy: validation
Validate before calling
if (await MANAGERS.aube.detect({ workspaceRoot })) {
const project = await MANAGERS.aube.read({ workspaceRoot });
} else {
// not an aube workspace — use getWorkspaceDetails() instead
} Type guard
function isUnexpectedManagerError(e: unknown): boolean {
return e instanceof ConvertError && e.type === "package_manager-unexpected";
} Try / catch
try {
const project = await MANAGERS.aube.read({ workspaceRoot });
} catch (e) {
if (e instanceof ConvertError && e.type === "package_manager-unexpected") {
// fall back to generic detection: getWorkspaceDetails({ root: workspaceRoot })
} else throw e;
} Prevention
- Never call a manager's read() without a preceding detect() in the same tick
- Prefer the getWorkspaceDetails() entry point, which handles detection for you
- Re-detect after any package.json mutation between reads
When it happens
Trigger: Calling MANAGERS.aube.read({ workspaceRoot }) directly on a project whose declared package manager is not aube (or whose aube lockfile is absent), or mutating package.json between getWorkspaceDetails()'s detect and read phases.
Common situations: Custom scripts or tests reaching into turbo-workspaces internals and calling read() without detect(); concurrent edits during conversion.
Related errors
- package_manager-unable_to_detect
- package_manager-unexpected
- Unable to update README.md
- May not specify workspace name in non-root turbo.json
- New workspace root detected - unexpected 'workspaces' field
AI-assisted analysis of vercel/turborepo@9f94a7d215 (2026-08-16).
Data as JSON: /api/errors/680fd8946aae51ac.
Report an issue: GitHub.