{"record":{"id":"0a275199a65c9640","repo":"Yeachan-Heo/oh-my-codex","slug":"fieldname-entries-must-be-strings","errorCode":null,"errorMessage":"${fieldName} entries must be strings","messagePattern":"(.+?) entries must be strings","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/team/api-interop.ts","lineNumber":449,"sourceCode":"    last_team_leader_nudge_event: summarizeEvent(latestLeaderNudgeEvent),\n    last_leader_notification_deferred_event: summarizeEvent(latestDeferredEvent),\n    source: {\n      summary_available: summary !== null,\n      snapshot_available: snapshot !== null,\n      phase_available: phaseState !== null,\n      recent_event_count: recentEvents.length,\n    },\n  };\n}\n\nfunction parseValidatedTaskIdArray(value: unknown, fieldName: string): string[] {\n  if (!Array.isArray(value)) {\n    throw new Error(`${fieldName} must be an array of task IDs (strings)`);\n  }\n  const taskIds: string[] = [];\n  for (const item of value) {\n    if (typeof item !== 'string') {\n      throw new Error(`${fieldName} entries must be strings`);\n    }\n    const normalized = item.trim();\n    if (!TASK_ID_SAFE_PATTERN.test(normalized)) {\n      throw new Error(`${fieldName} contains invalid task ID: \"${item}\"`);\n    }\n    taskIds.push(normalized);\n  }\n  return taskIds;\n}\n\nfunction teamStateExists(teamName: string, candidateCwd: string): boolean {\n  if (!TEAM_NAME_SAFE_PATTERN.test(teamName)) return false;\n  const teamRoot = join(resolveCanonicalTeamStateRoot(candidateCwd), 'team', teamName);\n  return existsSync(join(teamRoot, 'config.json')) || existsSync(join(teamRoot, 'tasks')) || existsSync(teamRoot);\n}\n\nfunction readTeamStateRootFromManifest(path: string): string | null {\n  if (!existsSync(path)) return null;","sourceCodeStart":431,"sourceCodeEnd":467,"githubUrl":"https://github.com/Yeachan-Heo/oh-my-codex/blob/3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2/src/team/api-interop.ts#L431-L467","documentation":"Thrown by parseValidatedTaskIdArray in src/team/api-interop.ts when validating team API operation arguments. It means a field expected to be an array of task IDs contains at least one entry that is not a string (e.g. a number or object). The library enforces strict string arrays before passing task IDs to the CLI interop layer.","triggerScenarios":"Calling executeTeamApiOperation with a field like task_ids: [101, 102] (numbers) or mixed types instead of ['101','102']. Any non-string element triggers this immediately.","commonSituations":"JSON input parsed from a hand-crafted file where task IDs were written as unquoted numbers; passing output of another tool that returns numeric IDs directly without mapping to strings.","solutions":["Convert all task ID entries to strings before calling the API: ids.map(String)","Check your --input JSON payload and quote every task ID value","Validate the array shape with Array.isArray and typeof checks before the call"],"exampleFix":"// before\napi('update-tasks', { task_ids: [101, 102] });\n// after\napi('update-tasks', { task_ids: ['101', '102'] });","handlingStrategy":"validation","validationCode":"const isTaskIdArray = (v: unknown): v is string[] =>\n  Array.isArray(v) && v.every((x) => typeof x === 'string');\nif (!isTaskIdArray(args.task_ids)) throw new TypeError('task_ids must be string[]');","typeGuard":"const isTaskIdArray = (v: unknown): v is string[] =>\n  Array.isArray(v) && v.every((x) => typeof x === 'string');","tryCatchPattern":null,"preventionTips":["Always map IDs through String() when crossing tool boundaries","Validate array payloads before calling executeTeamApiOperation"],"tags":["validation","team-api","type-mismatch"],"backgroundTag":"schema-validation-failed","analyzedSha":"3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2","analyzedAt":"2026-08-27T22:18:39.783Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}