{"record":{"id":"1d4cfd921d169f1e","repo":"mihomo-party-org/clash-party","slug":"failed-to-parse-process-list-json","errorCode":null,"errorMessage":"Failed to parse process list JSON:","messagePattern":"Failed to parse process list JSON:","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"src/main/core/process.ts","lineNumber":76,"sourceCode":"        `powershell -NoProfile -Command \"[Console]::OutputEncoding = [System.Text.Encoding]::UTF8; Get-Process | Where-Object {$_.ProcessName -like '*mihomo*'} | Select-Object Id,ProcessName | ConvertTo-Json\"`,\n        { encoding: 'utf8' }\n      )\n\n      if (stdout.trim()) {\n        managerLogger.info(`Found potential pipe-blocking processes: ${stdout}`)\n\n        try {\n          const processes = JSON.parse(stdout)\n          const processArray = Array.isArray(processes) ? processes : [processes]\n\n          for (const proc of processArray) {\n            const pid = proc.Id\n            if (pid && pid !== process.pid) {\n              await terminateProcess(pid)\n            }\n          }\n        } catch (parseError) {\n          managerLogger.warn('Failed to parse process list JSON:', parseError)\n          await fallbackTextParsing(stdout)\n        }\n      }\n    } catch (error) {\n      managerLogger.warn('Failed to check mihomo processes:', error)\n    }\n\n    await new Promise((resolve) => setTimeout(resolve, 1000))\n  } catch (error) {\n    managerLogger.error('Windows named pipe cleanup failed:', error)\n  }\n}\n\nasync function terminateProcess(pid: number): Promise<void> {\n  try {\n    process.kill(pid, 0)\n    process.kill(pid, 'SIGTERM')\n    managerLogger.info(`Terminated process ${pid} to free pipe`)","sourceCodeStart":58,"sourceCodeEnd":94,"githubUrl":"https://github.com/mihomo-party-org/clash-party/blob/911e090537acdf7c50bee1c3aebecc2ef119a8b5/src/main/core/process.ts#L58-L94","documentation":"In cleanupWindowsNamedPipes, the app runs a PowerShell/CIM query on Windows to enumerate mihomo processes, then JSON.parses stdout. When stdout is empty, truncated, or not JSON (localized output, older PowerShell returning text), JSON.parse throws and this warning is logged before falling back to fallbackTextParsing(stdout). Functionality continues via the text parser.","triggerScenarios":"JSON.parse(stdout) throws inside the process-list branch: empty stdout from ConvertTo-Json on empty result sets, PowerShell version < 3 without ConvertTo-Json, non-English locale output, or stderr noise mixed into the stream.","commonSituations":"Windows 7 / PowerShell 2.0 environments; `taskkill`-style query returning 'No results'; console codepage mangling output; the query matched zero mihomo processes so JSON is empty/blank.","solutions":["No action needed — fallbackTextParsing handles it; treat the warning as a signal the JSON path failed.","Upgrade Windows PowerShell (v3+) so ConvertTo-Json is available and output is stable JSON.","Harden the query to emit explicit JSON (e.g. wrap results in an array and force ConvertTo-Json -Compress) and trim/validate stdout before parsing."],"exampleFix":"// before\nconst list = JSON.parse(stdout)\n// after\nlet list = []\ntry {\n  list = JSON.parse(stdout.trim() || '[]')\n} catch {\n  list = parseProcessText(stdout) // deterministic text fallback\n}","handlingStrategy":"fallback","validationCode":"const trimmed = stdout?.trim()\nif (!trimmed || !trimmed.startsWith('{') && !trimmed.startsWith('[')) {\n  return parseProcessText(stdout) // skip JSON path entirely\n}","typeGuard":"const isProcessListJson = (v: unknown): v is { Id?: number }[] =>\n  Array.isArray(v) && v.every((x) => typeof x === 'object' && x !== null)","tryCatchPattern":"try {\n  const list = JSON.parse(stdout)\n  if (!isProcessListJson(list)) throw new Error('unexpected shape')\n} catch (parseError) {\n  managerLogger.warn('Failed to parse process list JSON:', parseError)\n  await fallbackTextParsing(stdout)\n}","preventionTips":["Force stable machine-readable output: `ConvertTo-Json -Compress -InputObject @(...)` with explicit culture.","Prefer CIM/CMDLET query paths available on the minimum supported Windows version, or use Native APIs.","Keep the text fallback tested so JSON failures never break pipe cleanup."],"tags":["windows","json-parse","process-list","fallback"],"backgroundTag":"json-parse-failed","analyzedSha":"911e090537acdf7c50bee1c3aebecc2ef119a8b5","analyzedAt":"2026-08-30T13:00:49.174Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}