{"record":{"id":"b1859e7132e63f0e","repo":"tinyhumansai/openhuman","slug":"agentteamapi-completetask-teamid-taskid-and-memb","errorCode":null,"errorMessage":"agentTeamApi.completeTask: teamId, taskId and memberId are required","messagePattern":"agentTeamApi\\.completeTask: teamId, taskId and memberId are required","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"app/src/services/api/agentTeamApi.ts","lineNumber":249,"sourceCode":"  },\n\n  /**\n   * Complete a claimed task, gating its transition to `done`. The core checks\n   * the quality invariants (dependencies done, the completer is the claimant and\n   * any pre-assigned owner, evidence present when `requireEvidence`) and returns\n   * a {@link CompletionOutcome}: `completed`, `gateFailed` (with reasons),\n   * `notClaimed`, or `unknownTask`. Evidence links accumulate across retries.\n   */\n  completeTask: async (params: {\n    teamId: string;\n    taskId: string;\n    memberId: string;\n    evidence?: string[];\n    requireEvidence?: boolean;\n  }): Promise<CompletionOutcome> => {\n    const { teamId, taskId, memberId, evidence = [], requireEvidence = false } = params;\n    if (!teamId || !taskId || !memberId) {\n      throw new Error('agentTeamApi.completeTask: teamId, taskId and memberId are required');\n    }\n    log('completeTask teamId=%s taskId=%s requireEvidence=%o', teamId, taskId, requireEvidence);\n    const response = await callCoreRpc<{ result: CompletionOutcome }>({\n      method: 'openhuman.agent_team_complete_task',\n      params: { teamId, taskId, memberId, evidence, requireEvidence },\n    });\n    log('completeTask kind=%s', response.result.kind);\n    return response.result;\n  },\n\n  /**\n   * Stop a member and release any task it is actively working on back to `todo`.\n   * Returns the stopped member plus the ids that were released.\n   */\n  shutdownMember: async (teamId: string, memberId: string): Promise<MemberShutdown> => {\n    if (!teamId || !memberId) {\n      throw new Error('agentTeamApi.shutdownMember: teamId and memberId are required');\n    }","sourceCodeStart":231,"sourceCodeEnd":267,"githubUrl":"https://github.com/tinyhumansai/openhuman/blob/a221052e0df5b1f7598fceba7329fd1af95d6699/app/src/services/api/agentTeamApi.ts#L231-L267","documentation":"Guard inside agentTeamApi.completeTask: all three identifiers (teamId, taskId, memberId) must be non-empty before the openhuman.agent_team_complete_task RPC runs. Any missing one means the caller cannot identify the completion target, so the client fails fast.","triggerScenarios":"Calling completeTask({ teamId, taskId }) with memberId omitted; passing a task row whose member assignment has not loaded yet; iterating tasks where some rows lack a claimedBy/member field.","commonSituations":"A 'Mark complete' button enabled before the task-member join data resolves; forms built from partial state; copy-pasting a call template and forgetting one field.","solutions":["Disable/withhold the complete action until all three ids are populated","Build the params from a single resolved task-with-member object so the fields cannot drift apart","Add a component-level check so the user gets feedback instead of a thrown error"],"exampleFix":"// before\nawait agentTeamApi.completeTask({ teamId, taskId: task.id }); // memberId missing\n\n// after\nif (!task.memberId) throw new Error('Task has no assigned member yet');\nawait agentTeamApi.completeTask({ teamId, taskId: task.id, memberId: task.memberId });","handlingStrategy":"validation","validationCode":"const canComplete = Boolean(teamId && task?.id && task?.memberId);\nif (canComplete) await agentTeamApi.completeTask({ teamId, taskId: task.id, memberId: task.memberId });","typeGuard":"const isCompleteTaskArgs = (a: { teamId?: string; taskId?: string; memberId?: string }): boolean =>\n  [a.teamId, a.taskId, a.memberId].every(v => typeof v === 'string' && v.length > 0);","tryCatchPattern":"try { await agentTeamApi.completeTask(params); }\ncatch (e) { if (String(e.message).includes('are required')) disableCompleteButton(); else throw e; }","preventionTips":["Derive all three ids from one resolved task-with-member row","Disable completion UI until the member join data is loaded","Prefer one source-of-truth object over three separately-managed fields"],"tags":["validation","agent-teams","required-field"],"backgroundTag":null,"analyzedSha":"a221052e0df5b1f7598fceba7329fd1af95d6699","analyzedAt":"2026-08-16T12:47:06.542Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}