yarnpkg/yarn · error · MessageError

The workspaces field in package.json must be an array.

Error message

The workspaces field in package.json must be an array.

What it means

Thrown by `resolveWorkspaces` after extracting the workspaces config from the root manifest: the `patterns` value (from `ws.packages`) must be an array. If `extractWorkspaces` returns a `packages` that is not an array (e.g. an object, string, or number), `Array.isArray(patterns)` is false and Yarn aborts because it cannot glob non-array patterns.

Source

Thrown at src/config.js:809

      previous = current;
      current = path.dirname(current);
    } while (current !== previous);

    return null;
  }

  async resolveWorkspaces(root: string, rootManifest: Manifest): Promise<WorkspacesManifestMap> {
    const workspaces = {};
    if (!this.workspacesEnabled) {
      return workspaces;
    }

    const ws = this.getWorkspaces(rootManifest, true);
    const patterns = ws && ws.packages ? ws.packages : [];

    if (!Array.isArray(patterns)) {
      throw new MessageError(this.reporter.lang('workspacesSettingMustBeArray'));
    }

    const registryFilenames = registryNames
      .map(registryName => this.registries[registryName].constructor.filename)
      .join('|');
    const trailingPattern = `/+(${registryFilenames})`;
    // anything under folder (node_modules) should be ignored, thus use the '**' instead of shallow match "*"
    const ignorePatterns = this.registryFolders.map(folder => `/${folder}/**/+(${registryFilenames})`);

    const files = await Promise.all(
      patterns.map(pattern =>
        fs.glob(pattern.replace(/\/?$/, trailingPattern), {
          cwd: root,
          ignore: ignorePatterns.map(ignorePattern => pattern.replace(/\/?$/, ignorePattern)),
        }),
      ),
    );

View on GitHub (pinned to c2dda503f3)

Solutions

  1. Ensure `workspaces.packages` is an array of glob strings: `"workspaces": {"packages": ["packages/*"]}`.
  2. Or use the shorthand array form: `"workspaces": ["packages/*"]`.
  3. Validate your package.json with `yarn init -y` dry-run or a JSON schema linter.

Example fix

// before (package.json)
{
  "workspaces": { "packages": "packages/*" }
}
// after
{
  "workspaces": ["packages/*"]
}
Defensive patterns

Strategy: type-guard

Validate before calling

const fs = require('fs');
const pkg = JSON.parse(fs.readFileSync('package.json', 'utf8'));
const packages = Array.isArray(pkg.workspaces) ? pkg.workspaces : pkg.workspaces && pkg.workspaces.packages;
if (!Array.isArray(packages)) {
  throw new Error('workspaces.packages must be an array of glob strings.');
}

Type guard

function isValidWorkspacesField(workspaces) {
  if (Array.isArray(workspaces)) return true;
  return workspaces != null && typeof workspaces === 'object' && Array.isArray(workspaces.packages);
}

Try / catch

try {
  await config.resolveWorkspaces(root, rootManifest);
} catch (err) {
  if (err.message.includes('must be an array')) {
    reporter.error('Fix the "workspaces" field in package.json to be an array.');
    process.exit(1);
  }
  throw err;
}

Prevention

When it happens

Trigger: Root package.json declares `"workspaces": {"packages": "packages/*"}` (a string instead of an array) or `"workspaces": {"packages": {}}` (an object). Any non-array shape for the `packages` key.

Common situations: Hand-editing package.json and using a string instead of array. Copying a config snippet from docs that used the shorthand array form into the object form incorrectly. A JSON transform mangled the array into an object.

Related errors


AI-assisted analysis of yarnpkg/yarn@c2dda503f3 (2026-08-13). Data as JSON: /api/errors/3cc611f54267ab39. Report an issue: GitHub.