agalwood/Motrix · error · AppError

IpcInvalidPayload

IpcInvalidPayload

Error message

Invalid Task Inspector Activity query params

What it means

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.

Source

Thrown at src/core/inspector-activity/task-inspector-activity-query.ts:30

   * Test-only fault injection. The first valid query delegates normally and
   * every later query fails without touching the runtime.
   */
  failAfterFirstQuery?: boolean
}

export interface TaskInspectorActivityQuery {
  snapshot(params: unknown): TaskInspectorActivitySnapshot
}

export function createTaskInspectorActivityQuery(
  reader: TaskInspectorActivitySnapshotReader,
  options: TaskInspectorActivityQueryOptions = {}
): TaskInspectorActivityQuery {
  let queryCount = 0
  return {
    snapshot(params: unknown): TaskInspectorActivitySnapshot {
      const invalid = (): never => {
        throw new AppError(
          ErrorCode.IpcInvalidPayload,
          'Invalid Task Inspector Activity query params'
        )
      }
      if (
        typeof params !== 'object' ||
        params === null ||
        (Object.getPrototypeOf(params) !== Object.prototype &&
          Object.getPrototypeOf(params) !== null)
      ) {
        return invalid()
      }
      const keys = Reflect.ownKeys(params)
      if (keys.length !== 1 || keys[0] !== 'taskId') {
        return invalid()
      }
      const descriptor = Object.getOwnPropertyDescriptor(params, 'taskId')
      if (!descriptor || !('value' in descriptor)) {

View on GitHub (pinned to 1a708ee577)

Solutions

  1. Always pass a plain object: query.snapshot({ taskId: '...', ... }) — never a primitive, array, or class instance.
  2. On the IPC sender side, JSON.stringify then parse to strip prototypes before calling.
  3. Default params to {} at the call site so an omitted argument cannot reach the guard.
  4. If you must accept a class instance, serialize it to a POJO first.

Example fix

// before
const snap = query.snapshot(someClassInstance) // throws IpcInvalidPayload

// after
const snap = query.snapshot({ taskId: someClassInstance.taskId, range: { from: 0, to: 100 } })
Defensive patterns

Strategy: type-guard

Validate before calling

// Only pass plain-object params to snapshot.
function toPlainParams(p: unknown): Record<string, unknown> {
  if (typeof p !== 'object' || p === null) return {}
  return Object.getPrototypeOf(p) === Object.prototype || Object.getPrototypeOf(p) === null ? p as Record<string, unknown> : { ...p }
}

Type guard

function isPlainObject(v: unknown): v is Record<string, unknown> {
  if (typeof v !== 'object' || v === null) return false
  const proto = Object.getPrototypeOf(v)
  return proto === Object.prototype || proto === null
}

Try / catch

if (!isPlainObject(params)) {
  // reject the IPC call with a 400-style response; do not call snapshot
}
const snap = query.snapshot(params)

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of agalwood/Motrix@1a708ee577 (2026-08-12). Data as JSON: /api/errors/772754cb95e1c6fe. Report an issue: GitHub.