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.workspaceRoot

View on GitHub (pinned to 9f94a7d215)

Solutions

  1. Use getWorkspaceDetails() instead of calling a manager's read() directly — it runs detect() first and only reads the matching manager
  2. If calling read() directly, run MANAGERS.aube.detect({ workspaceRoot }) first and bail on false
  3. 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

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


AI-assisted analysis of vercel/turborepo@9f94a7d215 (2026-08-16). Data as JSON: /api/errors/680fd8946aae51ac. Report an issue: GitHub.