{"record":{"id":"3cc611f54267ab39","repo":"yarnpkg/yarn","slug":"the-workspaces-field-in-package-json-must-be-an-ar","errorCode":null,"errorMessage":"The workspaces field in package.json must be an array.","messagePattern":"The workspaces field in package\\.json must be an array\\.","errorType":"validation","errorClass":"MessageError","httpStatus":null,"severity":"error","filePath":"src/config.js","lineNumber":809,"sourceCode":"\n      previous = current;\n      current = path.dirname(current);\n    } while (current !== previous);\n\n    return null;\n  }\n\n  async resolveWorkspaces(root: string, rootManifest: Manifest): Promise<WorkspacesManifestMap> {\n    const workspaces = {};\n    if (!this.workspacesEnabled) {\n      return workspaces;\n    }\n\n    const ws = this.getWorkspaces(rootManifest, true);\n    const patterns = ws && ws.packages ? ws.packages : [];\n\n    if (!Array.isArray(patterns)) {\n      throw new MessageError(this.reporter.lang('workspacesSettingMustBeArray'));\n    }\n\n    const registryFilenames = registryNames\n      .map(registryName => this.registries[registryName].constructor.filename)\n      .join('|');\n    const trailingPattern = `/+(${registryFilenames})`;\n    // anything under folder (node_modules) should be ignored, thus use the '**' instead of shallow match \"*\"\n    const ignorePatterns = this.registryFolders.map(folder => `/${folder}/**/+(${registryFilenames})`);\n\n    const files = await Promise.all(\n      patterns.map(pattern =>\n        fs.glob(pattern.replace(/\\/?$/, trailingPattern), {\n          cwd: root,\n          ignore: ignorePatterns.map(ignorePattern => pattern.replace(/\\/?$/, ignorePattern)),\n        }),\n      ),\n    );\n","sourceCodeStart":791,"sourceCodeEnd":827,"githubUrl":"https://github.com/yarnpkg/yarn/blob/c2dda503f3759b5be5f0e24ecd9cf5c97a540147/src/config.js#L791-L827","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Ensure `workspaces.packages` is an array of glob strings: `\"workspaces\": {\"packages\": [\"packages/*\"]}`.","Or use the shorthand array form: `\"workspaces\": [\"packages/*\"]`.","Validate your package.json with `yarn init -y` dry-run or a JSON schema linter."],"exampleFix":"// before (package.json)\n{\n  \"workspaces\": { \"packages\": \"packages/*\" }\n}\n// after\n{\n  \"workspaces\": [\"packages/*\"]\n}","handlingStrategy":"type-guard","validationCode":"const fs = require('fs');\nconst pkg = JSON.parse(fs.readFileSync('package.json', 'utf8'));\nconst packages = Array.isArray(pkg.workspaces) ? pkg.workspaces : pkg.workspaces && pkg.workspaces.packages;\nif (!Array.isArray(packages)) {\n  throw new Error('workspaces.packages must be an array of glob strings.');\n}","typeGuard":"function isValidWorkspacesField(workspaces) {\n  if (Array.isArray(workspaces)) return true;\n  return workspaces != null && typeof workspaces === 'object' && Array.isArray(workspaces.packages);\n}","tryCatchPattern":"try {\n  await config.resolveWorkspaces(root, rootManifest);\n} catch (err) {\n  if (err.message.includes('must be an array')) {\n    reporter.error('Fix the \"workspaces\" field in package.json to be an array.');\n    process.exit(1);\n  }\n  throw err;\n}","preventionTips":["Validate package.json against a JSON schema that enforces `workspaces` as an array.","Use the shorthand `\"workspaces\": [\"packages/*\"]` form to avoid the nested object pitfall.","Run `yarn install` after every manual package.json edit to catch shape errors early."],"tags":["workspaces","config","manifest","validation"],"backgroundTag":null,"analyzedSha":"c2dda503f3759b5be5f0e24ecd9cf5c97a540147","analyzedAt":"2026-08-13T04:17:06.305Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}