{"id":"44a7677979fd77a3","repo":"vitest-dev/vitest","slug":"unknown-value-for-test-listtags-listtags","errorCode":null,"errorMessage":"Unknown value for \"test.listTags\": ${listTags}","messagePattern":"Unknown value for \"test\\.listTags\": (.+?)","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/vitest/src/node/core.ts","lineNumber":498,"sourceCode":"    else if (listTags === 'json') {\n      const hasTags = [this.getRootProject(), ...this.projects].some(p => p.config.tags && p.config.tags.length > 0)\n      if (!hasTags) {\n        process.exitCode = 1\n        this.logger.printNoTestTagsFound()\n      }\n      else {\n        const manifest = {\n          tags: this.config.tags,\n          projects: this.projects.filter(p => p !== this.coreWorkspaceProject).map(p => ({\n            name: p.name,\n            tags: p.config.tags,\n          })),\n        }\n        this.logger.log(JSON.stringify(manifest, null, 2))\n      }\n    }\n    else {\n      throw new Error(`Unknown value for \"test.listTags\": ${listTags}`)\n    }\n  }\n\n  public async enableCoverage(): Promise<void> {\n    this.configOverride.coverage = {} as any\n    this.configOverride.coverage!.enabled = true\n    await this.createCoverageProvider()\n    await this.coverageProvider?.onEnabled?.()\n\n    // onFileTransform is the only thing that affects hash\n    if (this.coverageProvider?.onFileTransform) {\n      this.clearAllCachePaths()\n    }\n  }\n\n  public disableCoverage(): void {\n    this.configOverride.coverage ??= {} as any\n    this.configOverride.coverage!.enabled = false","sourceCodeStart":480,"sourceCodeEnd":516,"githubUrl":"https://github.com/vitest-dev/vitest/blob/d568f8ce3739b532d5bf2c1ee1e45e8a8a473d09/packages/vitest/src/node/core.ts#L480-L516","documentation":"The `test.listTags` option is typed as `boolean | 'json'`. When `vitest.listTags()` is called, core.ts:475-499 branches on those two shapes; any other value falls through to the throw at line 498 listing the offending value.","triggerScenarios":"Set `listTags: 'text'`, `listTags: 'yaml'`, or `listTags: 1` in config, then invoke the listTags flow.","commonSituations":"Guessing a format string not in the schema; passing a number expecting truthiness; copy-pasting from a different tool's API.","solutions":["Use `listTags: true` for the default human-readable tag listing.","Use `listTags: 'json'` for machine-readable JSON output.","Remove the option entirely if you did not intend to list tags."],"exampleFix":"// before\nexport default defineConfig({ test: { listTags: 'text' } })\n// after\nexport default defineConfig({ test: { listTags: true } })","handlingStrategy":"type-guard","validationCode":"function assertValidListTags(value: unknown) {\n  if (value !== undefined && value !== true && value !== false && value !== 'json') {\n    throw new Error(`test.listTags must be boolean or 'json', got ${JSON.stringify(value)}`)\n  }\n}","typeGuard":"function isValidListTags(value: unknown): value is boolean | 'json' {\n  return value === true || value === false || value === 'json' || value === undefined\n}","tryCatchPattern":null,"preventionTips":["Restrict listTags to true, false, or 'json'.","Avoid guessing format strings; check the type definition.","Remove the option if you do not need tag listing."],"tags":["config","tags","listtags","validation"],"analyzedSha":"d568f8ce3739b532d5bf2c1ee1e45e8a8a473d09","analyzedAt":"2026-08-03T20:23:56.861Z","schemaVersion":2}