{"record":{"id":"1654579be5d1d31e","repo":"docmirror/dev-sidecar","slug":"newconfig","errorCode":null,"errorMessage":"newConfig 为空，不做任何操作","messagePattern":"newConfig 为空，不做任何操作","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"packages/core/src/config-api.js","lineNumber":194,"sourceCode":"    }\n  },\n  doMerge: mergeApi.doMerge,\n  doDiff: mergeApi.doDiff,\n  /**\n   * 读取 config.json 后，合并配置\n   */\n  reload () {\n    const userConfig = configLoader.getUserConfig()\n    return configApi.set(userConfig) || {}\n  },\n  update (partConfig) {\n    const newConfig = lodash.merge(configApi.get(), partConfig)\n    configApi.save(newConfig)\n  },\n  get,\n  set (newConfig) {\n    if (newConfig == null) {\n      log.warn('newConfig 为空，不做任何操作')\n      return configTarget\n    }\n    return configApi.load(newConfig)\n  },\n  load (newConfig) {\n    const config = configLoader.getConfigFromFiles(newConfig, defConfig)\n    configTarget = config\n    return config\n  },\n  cloneDefault () {\n    return lodash.cloneDeep(defConfig)\n  },\n  addDefault (key, defValue) {\n    lodash.set(defConfig, key, defValue)\n  },\n  // 移除用户配置，用于恢复出厂设置功能\n  async removeUserConfig () {\n    const configPath = configLoader.getUserConfigPath()","sourceCodeStart":176,"sourceCodeEnd":212,"githubUrl":"https://github.com/docmirror/dev-sidecar/blob/7710cd56cce760c708f30b01d2d4056eb8c402d5/packages/core/src/config-api.js#L176-L212","documentation":"Warning logged by the set(newConfig) API in config-api.js when it is called with null or undefined. Instead of crashing, the function short-circuits and returns the current configTarget unchanged — no config is loaded or applied. It is a defensive no-op guard.","triggerScenarios":"Calling DevSidecar.config.set(null) or set(undefined) directly, or indirectly when configApi.save(diffConfig) produced a null/undefined diff (e.g. new config equals defaults and merge logic yields null) that is then passed back through set.","commonSituations":"GUI/CLI code that reads a persisted user override from ~/.dev-sidecar/config.json which is missing or empty and passes the result straight to set(); plugin code passing an optional config object that was never initialized; refactored callers that no longer build the partConfig before merging.","solutions":["Ensure the caller builds a real config object before calling set() (e.g. pass {} instead of null to load defaults).","If reading config from disk, fall back to {} when the file is missing/empty before calling set().","Check upstream logic that computes the diff/override passed to set() and fix the null source.","If null is intentional as a no-op, ignore the warning — behavior is safe and current config is returned."],"exampleFix":"// before\nconst part = readUserOverride(); // may be null\nDevSidecar.config.set(part)\n// after\nconst part = readUserOverride() || {}\nDevSidecar.config.set(part)","handlingStrategy":"type-guard","validationCode":"if (newConfig == null) {\n  console.warn('config is null, skipping set()')\n  return\n}\nDevSidecar.config.set(newConfig)","typeGuard":"function isConfigObject(v) {\n  return v != null && typeof v === 'object' && !Array.isArray(v)\n}","tryCatchPattern":null,"preventionTips":["Default optional config reads to {} before calling set().","Validate persisted config files (config.json) are non-empty before loading them.","Never pass through possibly-null computed diffs directly to set().","Treat this warning as a no-op signal: current config is returned unchanged."],"tags":["config","null-check","api-misuse","warning"],"backgroundTag":"null-config-argument","analyzedSha":"7710cd56cce760c708f30b01d2d4056eb8c402d5","analyzedAt":"2026-08-31T22:07:07.234Z","schemaVersion":2},"datasetVersion":"2026-08-31T22:30:34.772Z"}