{"record":{"id":"22944fe9a0de2a6f","repo":"Molunerfinn/PicGo","slug":"picgo-cloud-config-sync-local-config-invalid","errorCode":null,"errorMessage":"PICGO_CLOUD_CONFIG_SYNC_LOCAL_CONFIG_INVALID","messagePattern":"PICGO_CLOUD_CONFIG_SYNC_LOCAL_CONFIG_INVALID","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/main/events/rpc/routes/cloud.ts","lineNumber":140,"sourceCode":"}\n\nconst buildConfigSyncState = async (): Promise<IPicGoCloudConfigSyncState> => {\n  return {\n    sessionStatus: configSyncSessionStatus,\n    encryptionMethod: getLocalEncryptionMethod(),\n    lastSyncedAt: await getSnapshotUpdatedAt(),\n    conflicts: configSyncSessionStatus === IPicGoCloudConfigSyncSessionStatus.CONFLICT ? configSyncConflictItems : undefined\n  }\n}\n\nconst readLocalConfigWithComments = async (): Promise<IConfig> => {\n  if (!(await fs.pathExists(picgo.configPath))) {\n    return picgo.getConfig<IConfig>()\n  }\n  const content = await fs.readFile(picgo.configPath, 'utf8')\n  const parsed: unknown = parse(content)\n  if (!isPlainObject(parsed)) {\n    throw new Error(T('PICGO_CLOUD_CONFIG_SYNC_LOCAL_CONFIG_INVALID'))\n  }\n  return parsed as IConfig\n}\n\nconst extractConflictItems = (diffTree: IDiffNode): IPicGoCloudConfigSyncConflictItem[] => {\n  const items: IPicGoCloudConfigSyncConflictItem[] = []\n\n  const walk = (node: IDiffNode, pathSegments: string[]) => {\n    const nextSegments = node.key === 'root' ? pathSegments : [...pathSegments, node.key]\n\n    if (node.status === ConflictType.CONFLICT) {\n      // If the conflict is an object-level aggregation, surface leaf conflicts instead.\n      if (node.children && node.children.length > 0) {\n        node.children.forEach(child => walk(child, nextSegments))\n        return\n      }\n\n      items.push({","sourceCodeStart":122,"sourceCodeEnd":158,"githubUrl":"https://github.com/Molunerfinn/PicGo/blob/07ec7068a5512344da093d49a8408fa63ba3421e/src/main/events/rpc/routes/cloud.ts#L122-L158","documentation":"readLocalConfigWithComments parses ~/.picgo/config.json with a comment-preserving parser and requires the result to be a plain object before it is used for PicGo Cloud config sync. If the file parses to a non-object (array, string, number, null, or garbage), it throws PICGO_CLOUD_CONFIG_SYNC_LOCAL_CONFIG_INVALID. This protects the sync flow from operating on a structurally broken local config.","triggerScenarios":"Starting a cloud config sync when picgo.configPath exists but its content is not a JSON object — e.g. the file contains 'null', '[1,2]', a bare string, or content that a comment-tolerant parser resolves to a non-object.","commonSituations":"Config file truncated/corrupted by a crash or disk-full during write; user hand-edited config.json into invalid or non-object JSON; another tool overwrote the PicGo config with a different format.","solutions":["Open picgo.configPath (default ~/.picgo/config.json) and make it a valid JSON object, e.g. {}","Back up and delete/recreate the config file, letting PicGo regenerate defaults","Validate the file with JSON.parse (after stripping comments) before triggering cloud sync","Restore the config from a backup or re-configure uploaders via the UI"],"exampleFix":"// before\n~/.picgo/config.json => \"just a string\"\n// after\n~/.picgo/config.json => { \"picBed\": { \"current\": \"github\" } }","handlingStrategy":"type-guard","validationCode":"const raw = JSON.parse(stripJsonComments(fs.readFileSync(configPath, 'utf8')))\nif (raw === null || typeof raw !== 'object' || Array.isArray(raw)) {\n  throw new Error('config.json must be a JSON object')\n}","typeGuard":"function isPlainObject(v) {\n  return typeof v === 'object' && v !== null && !Array.isArray(v)\n}","tryCatchPattern":"try {\n  await startCloudSync()\n} catch (e) {\n  if (e.message.includes('LOCAL_CONFIG_INVALID')) {\n    await backupAndResetConfigFile(configPath)\n  } else throw e\n}","preventionTips":["Keep config.json a top-level JSON object; never write null/arrays","Back up ~/.picgo/config.json before hand-editing","Validate the file after any external tool touches it","Shut down PicGo cleanly to avoid truncated writes"],"tags":["config","json","sync","corrupt-config"],"backgroundTag":"invalid-config-file","analyzedSha":"07ec7068a5512344da093d49a8408fa63ba3421e","analyzedAt":"2026-08-30T01:45:22.289Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}