{"record":{"id":"d73076eb59571ae9","repo":"vitest-dev/vitest","slug":"error-instanceof-error-error-message-string","errorCode":null,"errorMessage":"${error instanceof Error ? error.message : String(error)}","messagePattern":"\\$\\{error instanceof Error \\? error\\.message : String\\(error\\)\\}","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/vitest/src/node/coverage.ts","lineNumber":900,"sourceCode":"    }\n\n    // \"export default defineConfig(...)\"\n    let config = resolveDefineConfig(mod)\n    if (config) {\n      return config\n    }\n\n    // \"export default mergeConfig(..., defineConfig(...))\"\n    if (mod.$type === 'function-call' && mod.$callee === 'mergeConfig') {\n      config = resolveMergeConfig(mod)\n      if (config) {\n        return config\n      }\n    }\n  }\n  catch (error) {\n    // Reduce magicast's verbose errors to readable ones\n    throw new Error(error instanceof Error ? error.message : String(error))\n  }\n\n  throw new Error(\n    'Failed to update coverage thresholds. Configuration file is too complex.',\n  )\n}\n\nfunction resolveDefineConfig(mod: any) {\n  if (mod.$type === 'function-call' && mod.$callee === 'defineConfig') {\n    // \"export default defineConfig({ test: {...} })\"\n    if (mod.$args[0].$type === 'object') {\n      return mod.$args[0]\n    }\n\n    if (mod.$args[0].$type === 'arrow-function-expression') {\n      if (mod.$args[0].$body.$type === 'object') {\n        // \"export default defineConfig(() => ({ test: {...} }))\"\n        return mod.$args[0].$body","sourceCodeStart":882,"sourceCodeEnd":918,"githubUrl":"https://github.com/vitest-dev/vitest/blob/1fa9837ec26533512fdcad8baebf249771bd340a/packages/vitest/src/node/coverage.ts#L882-L918","documentation":"Thrown from resolveConfig's catch when magicast cannot traverse the config AST. It reduces verbose magicast errors down to just the underlying error.message. Means the config's default export is not one of the recognized shapes (plain object, defineConfig call, mergeConfig call) and the traversal threw.","triggerScenarios":"autoUpdate calling resolveConfig on a default export magicast cannot statically parse — dynamic spreads, computed keys, configs wrapped in helpers other than defineConfig/mergeConfig, or ternaries.","commonSituations":"Highly dynamic config files; configs built with custom helper functions; conditional exports; spread of external objects.","solutions":["Read the captured message to identify the unparseable construct.","Simplify the config default export to a literal object or a defineConfig/mergeConfig call.","Move dynamic logic out of the default export (compute values into consts above it)."],"exampleFix":"// before\nexport default someCond ? { test: { ... } } : { test: { ... } }\n\n// after\nconst config = { test: { coverage: { thresholds: { lines: 80 } } } }\nexport default defineConfig(config)","handlingStrategy":"try-catch","validationCode":"function configIsStaticallyParseable(defaultExport) {\n  // magicast-style heuristic: must be object, defineConfig(...), or mergeConfig(...)\n  return defaultExport?.$type === 'object'\n    || (defaultExport?.$type === 'function-call'\n        && ['defineConfig', 'mergeConfig'].includes(defaultExport.$callee))\n}","typeGuard":null,"tryCatchPattern":"try {\n  await updateThresholds(...)\n} catch (e) {\n  if (/magicast|config/i.test(e.message)) {\n    // simplify config default export, then retry\n  } else throw e\n}","preventionTips":["Keep the config default export a literal object, defineConfig(...), or mergeConfig(...).","Compute dynamic values into consts above the export, not inside it.","Avoid ternaries and custom wrappers in the default export."],"tags":["coverage","thresholds","config-parse","magicast"],"backgroundTag":null,"analyzedSha":"1fa9837ec26533512fdcad8baebf249771bd340a","analyzedAt":"2026-08-11T16:11:39.638Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}