{"record":{"id":"772754cb95e1c6fe","repo":"agalwood/Motrix","slug":"ipcinvalidpayload","errorCode":"IpcInvalidPayload","errorMessage":"Invalid Task Inspector Activity query params","messagePattern":"Invalid Task Inspector Activity query params","errorType":"error_code","errorClass":"AppError","httpStatus":null,"severity":"error","filePath":"src/core/inspector-activity/task-inspector-activity-query.ts","lineNumber":30,"sourceCode":"   * Test-only fault injection. The first valid query delegates normally and\n   * every later query fails without touching the runtime.\n   */\n  failAfterFirstQuery?: boolean\n}\n\nexport interface TaskInspectorActivityQuery {\n  snapshot(params: unknown): TaskInspectorActivitySnapshot\n}\n\nexport function createTaskInspectorActivityQuery(\n  reader: TaskInspectorActivitySnapshotReader,\n  options: TaskInspectorActivityQueryOptions = {}\n): TaskInspectorActivityQuery {\n  let queryCount = 0\n  return {\n    snapshot(params: unknown): TaskInspectorActivitySnapshot {\n      const invalid = (): never => {\n        throw new AppError(\n          ErrorCode.IpcInvalidPayload,\n          'Invalid Task Inspector Activity query params'\n        )\n      }\n      if (\n        typeof params !== 'object' ||\n        params === null ||\n        (Object.getPrototypeOf(params) !== Object.prototype &&\n          Object.getPrototypeOf(params) !== null)\n      ) {\n        return invalid()\n      }\n      const keys = Reflect.ownKeys(params)\n      if (keys.length !== 1 || keys[0] !== 'taskId') {\n        return invalid()\n      }\n      const descriptor = Object.getOwnPropertyDescriptor(params, 'taskId')\n      if (!descriptor || !('value' in descriptor)) {","sourceCodeStart":12,"sourceCodeEnd":48,"githubUrl":"https://github.com/agalwood/Motrix/blob/1a708ee57746c434e2c67a44bbf0906a976afea4/src/core/inspector-activity/task-inspector-activity-query.ts#L12-L48","documentation":"Thrown by the Task Inspector Activity query when the params passed to snapshot() are not a plain object. The guard rejects anything that is not an object, is null, or whose prototype is neither Object.prototype nor null — defending the IPC boundary against arrays, class instances, primitives, and cross-realm objects. Categorized as IpcInvalidPayload.","triggerScenarios":"snapshot(params) is called with params that is not a plain object literal: an array, a class instance, a primitive (string/number/boolean), null/undefined, or an object from another realm/VM context whose prototype chain differs.","commonSituations":"IPC renderer sending a raw primitive or array instead of a params object; a class instance leaking across the IPC boundary instead of a serialized POJO; an undefined default when no argument was supplied; a cross-realm/electron-remote object.","solutions":["Always pass a plain object: query.snapshot({ taskId: '...', ... }) — never a primitive, array, or class instance.","On the IPC sender side, JSON.stringify then parse to strip prototypes before calling.","Default params to {} at the call site so an omitted argument cannot reach the guard.","If you must accept a class instance, serialize it to a POJO first."],"exampleFix":"// before\nconst snap = query.snapshot(someClassInstance) // throws IpcInvalidPayload\n\n// after\nconst snap = query.snapshot({ taskId: someClassInstance.taskId, range: { from: 0, to: 100 } })","handlingStrategy":"type-guard","validationCode":"// Only pass plain-object params to snapshot.\nfunction toPlainParams(p: unknown): Record<string, unknown> {\n  if (typeof p !== 'object' || p === null) return {}\n  return Object.getPrototypeOf(p) === Object.prototype || Object.getPrototypeOf(p) === null ? p as Record<string, unknown> : { ...p }\n}","typeGuard":"function isPlainObject(v: unknown): v is Record<string, unknown> {\n  if (typeof v !== 'object' || v === null) return false\n  const proto = Object.getPrototypeOf(v)\n  return proto === Object.prototype || proto === null\n}","tryCatchPattern":"if (!isPlainObject(params)) {\n  // reject the IPC call with a 400-style response; do not call snapshot\n}\nconst snap = query.snapshot(params)","preventionTips":["Always pass object literals ({...}) over IPC.","JSON round-trip payloads at the boundary to strip prototypes.","Default optional params to {}.","Never forward class instances or arrays as the params root."],"tags":["ipc","validation","payload","typescript","boundary"],"backgroundTag":null,"analyzedSha":"1a708ee57746c434e2c67a44bbf0906a976afea4","analyzedAt":"2026-08-12T16:18:09.346Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}