{"record":{"id":"09a8134af583bf78","repo":"agalwood/Motrix","slug":"ipcinvalidpayload-09a813","errorCode":"IpcInvalidPayload","errorMessage":"Invalid task create request: ${parsed.error.message}","messagePattern":"Invalid task create request: (.+?)","errorType":"exception","errorClass":"AppError","httpStatus":null,"severity":"error","filePath":"src/core/task/create-task-handler.ts","lineNumber":163,"sourceCode":" *      subsequent polling updates merge onto an already-present record\n *      (preserving diskPath / finalPath / finalName / transitionPhase /\n *      torrentMetaPath).\n *\n * The legacy IPC contract returned only `{ gid }`; the result now also\n * carries the freshly-minted `taskId` (== DownloadTask.id) so callers\n * that need the stable public identifier (notably the MDXP bridge, where\n * gid can rotate across instance swaps) don't have to reach into\n * TaskManager to look it up. Renderer-facing IPC paths still narrow to\n * `{ gid }` structurally — the extra field is harmless excess.\n */\nexport async function handleCreateTask(\n  rawRequest: unknown,\n  deps: CreateTaskDeps,\n  opts: CreateTaskOptions = {}\n): Promise<{ gid: string; taskId: string }> {\n  const parsed = taskCreateRequestSchema.safeParse(rawRequest)\n  if (!parsed.success) {\n    throw new AppError(\n      ErrorCode.IpcInvalidPayload,\n      `Invalid task create request: ${parsed.error.message}`\n    )\n  }\n\n  const req = parsed.data\n  const appSettings = deps.settingsManager.getApp()\n  const engineSettings = deps.settingsManager.getEngine()\n\n  const requestedSaveDir = req.saveDir || appSettings.defaultSaveDir\n  const effectiveSaveDir = deps.prepareSaveDir\n    ? await deps.prepareSaveDir(requestedSaveDir)\n    : requestedSaveDir\n\n  log.info(\n    {\n      type: req.type,\n      payloadKind: req.type === 'bt' ? req.payload.kind : 'http',","sourceCodeStart":145,"sourceCodeEnd":181,"githubUrl":"https://github.com/agalwood/Motrix/blob/1a708ee57746c434e2c67a44bbf0906a976afea4/src/core/task/create-task-handler.ts#L145-L181","documentation":"Thrown by create-task-handler.ts:163 when `taskCreateRequestSchema.safeParse(rawRequest)` fails. The incoming IPC payload does not conform to the task-create schema; the parser's structured error is appended to the message. This is the trust-boundary validation for renderer/submitted create requests.","triggerScenarios":"Missing required fields (e.g. no `uris`); wrong field types (uris not array, saveDir not string); malformed URI entries; extra/renamed fields after a schema change without renderer update; a third-party caller sending an outdated payload shape.","commonSituations":"Renderer/schema version skew after an update; a browser-protocol or external caller sending hand-rolled JSON; copy-paste error in the request construction; i18n/escape bug corrupting the payload.","solutions":["Read `parsed.error.message` to find the offending field and align the caller's payload with `taskCreateRequestSchema`.","Keep renderer and main schema versions in lockstep — re-export the schema as the single source of truth.","Validate on the renderer side before the IPC call to give the user immediate feedback.","If extending the payload, add new fields as optional and migrate the renderer first."],"exampleFix":"// before\nconst parsed = taskCreateRequestSchema.safeParse(rawRequest)\nif (!parsed.success) {\n  throw new AppError(ErrorCode.IpcInvalidPayload, `Invalid task create request: ${parsed.error.message}`)\n}\n\n// after — surface zod issues to the caller for actionable feedback\nconst parsed = taskCreateRequestSchema.safeParse(rawRequest)\nif (!parsed.success) {\n  const issues = parsed.error.issues.map(i => `${i.path.join('.')}: ${i.message}`).join('; ')\n  throw new AppError(ErrorCode.IpcInvalidPayload, `Invalid task create request: ${issues}`)\n}","handlingStrategy":"validation","validationCode":"import { taskCreateRequestSchema } from '@shared/schemas/task-create'\nconst check = taskCreateRequestSchema.safeParse(candidate)\nif (!check.success) {\n  const issues = check.error.issues.map(i => `${i.path.join('.')}: ${i.message}`)\n  // show issues to the user before sending the IPC\n}","typeGuard":"function isInvalidPayload(e) { return e instanceof AppError && e.code === ErrorCode.IpcInvalidPayload }","tryCatchPattern":"const parsed = taskCreateRequestSchema.safeParse(rawRequest)\nif (!parsed.success) {\n  throw new AppError(ErrorCode.IpcInvalidPayload, `Invalid task create request: ${parsed.error.issues.map(i => i.path.join('.') + ': ' + i.message).join('; ')}`)\n}","preventionTips":["Keep the renderer and main schema in lockstep — export one source of truth.","Validate in the renderer before the IPC call for immediate feedback.","Add new payload fields as optional and migrate callers first.","Use the schema to generate the renderer's request types."],"tags":["ipc","validation","schema","create","zod"],"backgroundTag":null,"analyzedSha":"1a708ee57746c434e2c67a44bbf0906a976afea4","analyzedAt":"2026-08-12T16:18:09.346Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}