tinyhumansai/openhuman · error
agentTeamApi.startMember: teamId and memberId are required
Error message
agentTeamApi.startMember: teamId and memberId are required
What it means
Guard inside agentTeamApi.startMember: both teamId and memberId must be non-empty before the openhuman.agent_team_start_member RPC claims a task and spawns the member's worker. taskId is optional (the core then claims the next claimable task), but the two identity fields are mandatory.
Source
Thrown at app/src/services/api/agentTeamApi.ts:326
payload: readMessagePayload(event.payload),
timestamp: event.timestamp,
};
},
/**
* Start a live run for a member: the core claims a task (the explicit `taskId`,
* else the member's next claimable one) and spawns a worker that runs it to
* completion. Returns a {@link StartMemberOutcome} — `started` (worker
* dispatched) or a reason no work began.
*/
startMember: async (params: {
teamId: string;
memberId: string;
taskId?: string;
}): Promise<StartMemberOutcome> => {
const { teamId, memberId, taskId } = params;
if (!teamId || !memberId) {
throw new Error('agentTeamApi.startMember: teamId and memberId are required');
}
log('startMember teamId=%s memberId=%s taskId=%o', teamId, memberId, taskId);
const response = await callCoreRpc<{ result: StartMemberOutcome }>({
method: 'openhuman.agent_team_start_member',
params: { teamId, memberId, ...(taskId ? { taskId } : {}) },
});
log('startMember kind=%s', response.result.kind);
return response.result;
},
};
View on GitHub (pinned to a221052e0d)
Solutions
- Gate the start action on both ids being non-empty
- Bind the handler to the full member row so both ids come from one object
- Show a disabled state with a tooltip while data loads instead of relying on the throw
Example fix
// before
<button onClick={() => agentTeamApi.startMember({ teamId, memberId: row.id ?? '' })}>Start</button>
// after
<button disabled={!teamId || !row.id} onClick={() => agentTeamApi.startMember({ teamId, memberId: row.id })}>Start</button> Defensive patterns
Strategy: validation
Validate before calling
const canStart = Boolean(teamId && member?.id);
if (canStart) await agentTeamApi.startMember({ teamId, memberId: member.id }); Type guard
const isNonEmptyString = (v: unknown): v is string => typeof v === 'string' && v.length > 0;
Try / catch
try { const out = await agentTeamApi.startMember({ teamId, memberId }); }
catch (e) { if (String(e.message).includes('required')) disableStartButton(); else throw e; } Prevention
- Gate start controls on both ids from the same row object
- Keep optional taskId optional — only the two identity fields are hard requirements
- Show loading placeholders as disabled, not as actionable rows
When it happens
Trigger: Calling startMember({ memberId }) with no teamId, or startMember({ teamId, memberId: '' }) — e.g. a 'Run' button on a member card before the team context resolves.
Common situations: Start action enabled by default on skeleton/loading rows; member id read from an optional field of a differently-shaped object; team id kept in a parent that has not mounted its value yet.
Related errors
- agentTeamApi.get: teamId is required
- agentTeamApi.listMessages: teamId is required
- agentTeamApi.completeTask: teamId, taskId and memberId are r
- agentTeamApi.shutdownMember: teamId and memberId are require
- agentTeamApi.messageMember: teamId is required
AI-assisted analysis of tinyhumansai/openhuman@a221052e0d (2026-08-16).
Data as JSON: /api/errors/14578ae26753aaf1.
Report an issue: GitHub.