{"record":{"id":"1b2efdeb029c5220","repo":"eyaltoledano/claude-task-master","slug":"for-file-storage-taskid-must-be-a-positive-intege","errorCode":null,"errorMessage":"For file storage, taskId must be a positive integer. Use update-subtask-by-id for IDs like \"1.2\", or run in API storage for display IDs (e.g., \"HAM-123\").","messagePattern":"For file storage, taskId must be a positive integer\\. Use update-subtask-by-id for IDs like \"1\\.2\", or run in API storage for display IDs \\(e\\.g\\., \"HAM-123\"\\)\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"scripts/modules/task-manager/update-task-by-id.js","lineNumber":140,"sourceCode":"\t\tif (remoteResult) {\n\t\t\treturn remoteResult;\n\t\t}\n\t\t// Otherwise fall through to file-based logic below\n\t\t// --- End BRIDGE ---\n\n\t\t// For file storage, ensure the tasks file exists\n\t\tif (!fs.existsSync(tasksPath))\n\t\t\tthrow new Error(`Tasks file not found: ${tasksPath}`);\n\t\t// --- End Input Validations ---\n\n\t\t// --- Task Loading and Status Check (Keep existing) ---\n\t\tconst data = readJSON(tasksPath, projectRoot, tag);\n\t\tif (!data || !data.tasks)\n\t\t\tthrow new Error(`No valid tasks found in ${tasksPath}.`);\n\t\t// File storage requires a strict numeric task ID\n\t\tconst idStr = String(taskId).trim();\n\t\tif (!/^\\d+$/.test(idStr)) {\n\t\t\tthrow new Error(\n\t\t\t\t'For file storage, taskId must be a positive integer. ' +\n\t\t\t\t\t'Use update-subtask-by-id for IDs like \"1.2\", or run in API storage for display IDs (e.g., \"HAM-123\").'\n\t\t\t);\n\t\t}\n\t\tconst numericTaskId = Number(idStr);\n\t\tconst taskIndex = data.tasks.findIndex((task) => task.id === numericTaskId);\n\t\tif (taskIndex === -1) {\n\t\t\treport('error', `Task with ID ${numericTaskId} not found`);\n\t\t\tthrow new Error(`Task with ID ${numericTaskId} not found.`);\n\t\t}\n\t\tconst taskToUpdate = data.tasks[taskIndex];\n\t\tif (taskToUpdate.status === 'done' || taskToUpdate.status === 'completed') {\n\t\t\treport(\n\t\t\t\t'warn',\n\t\t\t\t`Task ${taskId} is already marked as done and cannot be updated`\n\t\t\t);\n\n\t\t\t// Only show warning box for text output (CLI)","sourceCodeStart":122,"sourceCodeEnd":158,"githubUrl":"https://github.com/eyaltoledano/claude-task-master/blob/c0c98d367c55296bfe69e65680625b6db437af02/scripts/modules/task-manager/update-task-by-id.js#L122-L158","documentation":"When using file storage, updateTaskById() only accepts strictly numeric task IDs (matching /^\\d+$/). Alphanumeric or dotted display IDs like 'HAM-123' or '1.2' are rejected because file-based tasks.json keys tasks by integer id; subtask-style IDs belong to update-subtask-by-id and display IDs to API storage.","triggerScenarios":"Calling updateTaskById('1.2', prompt) instead of updateSubtaskById; calling with 'HAM-123' while configured for file storage; passing strings with whitespace-plus-suffix like '5 ' handled, but 'task-5' or '5.0' rejected.","commonSituations":"Copy-pasting display IDs from Hamster/API-backed views into a local file-storage project; mixing up update-task-by-id and update-subtask-by-id; scripts written against API storage run against file storage.","solutions":["Use a plain integer ID (e.g., '5') with updateTaskById in file storage","For dotted subtask IDs ('1.2'), call updateSubtaskById instead","For display IDs ('HAM-123'), run against API (Hamster) storage rather than file storage","Normalize/parse the incoming ID in your script to extract the numeric portion when appropriate"],"exampleFix":"// before\nawait updateTaskById('1.2', prompt); // rejected in file storage\n// after\nawait updateSubtaskById('1.2', prompt); // subtask update\n// or\nawait updateTaskById(1, prompt); // numeric parent ID","handlingStrategy":"validation","validationCode":"function routeUpdate(taskId) {\n  const id = String(taskId).trim();\n  if (/^\\d+$/.test(id)) return updateTaskById(Number(id), prompt);\n  if (/^\\d+\\.\\d+$/.test(id)) return updateSubtaskById(id, prompt);\n  throw new Error(`ID '${taskId}' requires API storage; numeric IDs only for file storage`);\n}","typeGuard":"function isNumericTaskId(taskId) {\n  return /^\\d+$/.test(String(taskId).trim());\n}","tryCatchPattern":"try {\n  await updateTaskById(taskId, prompt);\n} catch (err) {\n  if (err.message.includes('must be a positive integer')) {\n    console.error('Use update-subtask-by-id for 1.2-style IDs, or Hamster/API storage for HAM-123');\n  } else throw err;\n}","preventionTips":["Normalize IDs before calling: strip prefixes and route dotted IDs to update-subtask-by-id","Know your storage mode: file storage = integer IDs only; display IDs need API storage","Never pass display IDs (HAM-123) into file-storage commands","Add ID-format assertions at the entry point of scripts"],"tags":["validation","task-management","ids","file-storage"],"backgroundTag":"invalid-task-id-format","analyzedSha":"c0c98d367c55296bfe69e65680625b6db437af02","analyzedAt":"2026-08-29T02:56:26.071Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}