{"record":{"id":"018d074a2effcd08","repo":"angular/angular-cli","slug":"invalid-config-found-at-wksp-filepath-extensi","errorCode":null,"errorMessage":"Invalid config found at ${wksp.filePath}. `extensions.cli` should be an object.","messagePattern":"Invalid config found at (.+?)\\. `extensions\\.cli` should be an object\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/angular/cli/src/utilities/completion.ts","lineNumber":116,"sourceCode":"  return undefined;\n}\n\nasync function getCompletionConfig(): Promise<CompletionConfig | undefined> {\n  const wksp = await getWorkspace('global');\n\n  return wksp?.getCli()?.['completion'];\n}\n\nasync function setCompletionConfig(config: CompletionConfig): Promise<void> {\n  const wksp = await getWorkspace('global');\n  if (!wksp) {\n    throw new Error(`Could not find global workspace`);\n  }\n\n  wksp.extensions['cli'] ??= {};\n  const cli = wksp.extensions['cli'];\n  if (!json.isJsonObject(cli)) {\n    throw new Error(\n      `Invalid config found at ${wksp.filePath}. \\`extensions.cli\\` should be an object.`,\n    );\n  }\n  cli.completion = config as json.JsonObject;\n  await wksp.save();\n}\n\nasync function shouldPromptForAutocompletionSetup(\n  command: string,\n  config?: CompletionConfig,\n): Promise<boolean> {\n  // Force whether or not to prompt for autocomplete to give an easy path for e2e testing to skip.\n  if (forceAutocomplete !== undefined) {\n    return forceAutocomplete;\n  }\n\n  // Don't prompt on `ng update`, 'ng version' or `ng completion`.\n  if (['version', 'update', 'completion'].includes(command)) {","sourceCodeStart":98,"sourceCodeEnd":134,"githubUrl":"https://github.com/angular/angular-cli/blob/bb72145f9ab45aee29f523236b3a25cd0813a841/packages/angular/cli/src/utilities/completion.ts#L98-L134","documentation":"Thrown by setCompletionConfig when the global workspace's `extensions.cli` value exists but is not a JSON object (e.g. a string, number, or array). The CLI expects `extensions.cli` to be an object so it can write `cli.completion`; a malformed value would otherwise be silently overwritten or corrupted.","triggerScenarios":"The global Angular config file contains a `cli` entry under extensions whose value is a non-object (manually edited file, older/corrupted config, or another tool writing a scalar to that key), and any ng command triggers considerSettingUpAutocompletion -> setCompletionConfig.","commonSituations":"Users hand-editing their global Angular config and setting `\"cli\": true` or a string, config files damaged by editors or sync tools, or configs written by tooling incompatible with the CLI's schema.","solutions":["Open the file reported in the error message (wksp.filePath, typically the global angular config) and change `extensions.cli` to an object, e.g. \"cli\": { \"completion\": {} }.","Delete the malformed `cli` key (or the whole file) and let the CLI regenerate a valid config on the next run.","Fix any tooling/sync process that wrote the scalar value to extensions.cli.","Wrap the setup flow in try/catch to log and skip completion setup when the global config is malformed."],"exampleFix":"// before (global angular config)\n{ \"extensions\": { \"cli\": true } }\n// after\n{ \"extensions\": { \"cli\": { \"completion\": { \"prompted\": true } } } }","handlingStrategy":"validation","validationCode":"import { json } from '@angular-devkit/core';\nconst config = JSON.parse(fs.readFileSync(globalConfigPath, 'utf8'));\nconst cli = config?.extensions?.cli;\nif (cli !== undefined && !json.isJsonObject(cli)) {\n  throw new Error(`${globalConfigPath}: extensions.cli must be an object, got ${typeof cli}`);\n}","typeGuard":"function isJsonObject(v: unknown): v is Record<string, json.JsonValue> {\n  return typeof v === 'object' && v !== null && !Array.isArray(v);\n}","tryCatchPattern":"try {\n  await setCompletionConfig(config);\n} catch (err) {\n  if ((err as Error).message.includes('`extensions.cli` should be an object')) {\n    logger.error(`Fix extensions.cli in the file named in the error (set it to an object)`);\n  } else throw err;\n}","preventionTips":["Never assign scalars to `cli` in the global Angular config; keep it an object","Validate the global config JSON after manual edits or sync-tool runs","Back up ~/.angular-config before editing","Fail soft on completion setup so a malformed global config cannot break ng commands"],"tags":["angular-cli","completion","config-validation","schema"],"backgroundTag":"schema-validation-failed","analyzedSha":"bb72145f9ab45aee29f523236b3a25cd0813a841","analyzedAt":"2026-08-30T02:47:34.745Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}