{"record":{"id":"0036271d028c279f","repo":"eyaltoledano/claude-task-master","slug":"parsed-ai-response-for-updated-tasks-was-not-an-ar","errorCode":null,"errorMessage":"Parsed AI response for updated tasks was not an array.","messagePattern":"Parsed AI response for updated tasks was not an array\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"scripts/modules/task-manager/update-tasks.js","lineNumber":252,"sourceCode":"\t\t\t\t\tdependencies: task.dependencies ?? [],\n\t\t\t\t\tpriority: task.priority ?? null,\n\t\t\t\t\tdetails: task.details ?? null,\n\t\t\t\t\ttestStrategy: task.testStrategy ?? null,\n\t\t\t\t\tsubtasks: task.subtasks\n\t\t\t\t\t\t? task.subtasks.map((subtask) => ({\n\t\t\t\t\t\t\t\t...subtask,\n\t\t\t\t\t\t\t\tdependencies: subtask.dependencies ?? [],\n\t\t\t\t\t\t\t\tstatus: subtask.status ?? 'pending',\n\t\t\t\t\t\t\t\ttestStrategy: subtask.testStrategy ?? null\n\t\t\t\t\t\t\t}))\n\t\t\t\t\t\t: null\n\t\t\t\t})\n\t\t\t);\n\n\t\t\t// --- Update Tasks Data (Updated writeJSON call) ---\n\t\t\tif (!Array.isArray(parsedUpdatedTasks)) {\n\t\t\t\t// Should be caught by parser, but extra check\n\t\t\t\tthrow new Error(\n\t\t\t\t\t'Parsed AI response for updated tasks was not an array.'\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (isMCP)\n\t\t\t\tlogFn.info(\n\t\t\t\t\t`Received ${parsedUpdatedTasks.length} updated tasks from AI.`\n\t\t\t\t);\n\t\t\telse\n\t\t\t\tlogFn(\n\t\t\t\t\t'info',\n\t\t\t\t\t`Received ${parsedUpdatedTasks.length} updated tasks from AI.`\n\t\t\t\t);\n\t\t\t// Create a map for efficient lookup\n\t\t\tconst updatedTasksMap = new Map(\n\t\t\t\tparsedUpdatedTasks.map((task) => [task.id, task])\n\t\t\t);\n\n\t\t\tlet actualUpdateCount = 0;","sourceCodeStart":234,"sourceCodeEnd":270,"githubUrl":"https://github.com/eyaltoledano/claude-task-master/blob/c0c98d367c55296bfe69e65680625b6db437af02/scripts/modules/task-manager/update-tasks.js#L234-L270","documentation":"The AI is asked to return an array of updated tasks. After parsing the response (which usually enforces array-ness), updateTasks re-checks Array.isArray(parsedUpdatedTasks) as a defense-in-depth guard and throws if it is not an array. It signals the AI output did not match the expected batch-update schema.","triggerScenarios":"AI response parsed (e.g. from a JSON blob in text) into a non-array value — an object, null, or string — during the update-tasks batch operation.","commonSituations":"Model returning a single object instead of an array when only one task changes, malformed JSON wrapped in prose, or context overflow truncating the response.","solutions":["Retry the operation; AI output variance is often transient","Use --research or a stronger model for the batch update","Reduce the number of tasks updated in one call (lower fromId scope or update fewer tasks)","Check provider connectivity/model config if malformed responses recur"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"if (!Array.isArray(parsedUpdatedTasks)) {\n  // retry the AI call or fall back to per-task updates\n}","typeGuard":"const isUpdatedTasksArray = (v) => Array.isArray(v) && v.every((t) => t && typeof t === 'object' && typeof t.id !== 'undefined');","tryCatchPattern":"try {\n  await updateTasks(...);\n} catch (e) {\n  if (e.message.includes('was not an array')) {\n    // retry with stronger model or smaller batch\n  } else throw e;\n}","preventionTips":["Batch fewer tasks per update call","Use research-tier models for multi-task operations","Verify parsed JSON shape before writing","Retry once on schema failures before surfacing to users"],"tags":["ai","response-validation","array-schema","api-response"],"backgroundTag":"invalid-ai-response-schema","analyzedSha":"c0c98d367c55296bfe69e65680625b6db437af02","analyzedAt":"2026-08-29T02:56:26.071Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}