vercel/turborepo · error · ConvertError

pnpm-workspace_parse_error

pnpm-workspace_parse_error

Error message

failed to parse ${workspaceFile}

What it means

When expanding pnpm workspace globs, utils reads pnpm-workspace.yaml with js-yaml; if yaml.load throws (a YAMLException such as bad indentation or duplicate keys), it becomes ConvertError `failed to parse <path>` with type pnpm-workspace_parse_error. Note that a syntactically valid file with the wrong shape (packages missing or not an array) does NOT throw here — the function silently returns [].

Solutions

  1. Run `pnpm install` in the repo — pnpm itself will report the exact YAML error location
  2. Replace tab indentation with spaces and fix the flagged construct
  3. Lint the file with any YAML validator, then rerun the conversion

Example fix

# before (tab indentation)
packages:
	- "apps/*"
	- "packages/*"
# after
packages:
  - "apps/*"
  - "packages/*"
Defensive patterns

Strategy: validation

Validate before calling

import { readFileSync, existsSync } from "fs-extra";
import yaml from "js-yaml";
if (existsSync(workspaceFile)) {
  try {
    yaml.load(readFileSync(workspaceFile, "utf8"));
  } catch (e) {
    throw new Error(`pnpm-workspace.yaml is invalid: ${(e as Error).message}`);
  }
}

Type guard

function isConvertError(e: unknown): e is { type: string } {
  return typeof e === "object" && e !== null && "type" in e;
}

Try / catch

try {
  await read(args);
} catch (e) {
  if (isConvertError(e) && e.type === "pnpm-workspace_parse_error") {
    // run `pnpm install` to get pnpm's own error location, fix YAML, retry
  } else {
    throw e;
  }
}

Prevention

When it happens

Trigger: pnpm-workspace.yaml containing tab characters for indentation, a malformed mapping, an unclosed quote, or duplicate keys; the file being hand-edited just before a workspace conversion reads it.

Common situations: Editors inserting tabs into YAML; pasting config from blog posts that mangle indentation; schema drift after a pnpm major version changes allowed keys.

Understand the failure class

Related errors


AI-assisted analysis of vercel/turborepo@f9245100cf (2026-08-17). Data as JSON: /api/errors/77b87b70ed42a12b. Report an issue: GitHub.

Appendix: source

Thrown at packages/turbo-workspaces/src/utils.ts:373

  workspaceFileName
}: {
  workspaceRoot: string;
  workspaceFileName: string;
}): Array<string> {
  const workspaceFile = path.join(workspaceRoot, workspaceFileName);
  if (existsSync(workspaceFile)) {
    try {
      const workspaceConfig = yaml.load(readFileSync(workspaceFile, "utf8"));
      // validate it's the type we expect
      if (
        workspaceConfig instanceof Object &&
        "packages" in workspaceConfig &&
        Array.isArray(workspaceConfig.packages)
      ) {
        return workspaceConfig.packages as Array<string>;
      }
    } catch (err) {
      throw new ConvertError(`failed to parse ${workspaceFile}`, {
        type: "pnpm-workspace_parse_error"
      });
    }
  }

  return [];
}

function expandPaths({
  root,
  lockFile,
  workspaceConfig
}: {
  root: string;
  lockFile: string;
  workspaceConfig?: string;
}) {
  const fromRoot = (p: string) => path.join(root, p);

View on GitHub (pinned to f9245100cf)