tinyhumansai/openhuman · error
agentTeamApi.shutdownMember: teamId and memberId are require
Error message
agentTeamApi.shutdownMember: teamId and memberId are required
What it means
Guard inside agentTeamApi.shutdownMember: both teamId and memberId must be non-empty before the openhuman.agent_team_shutdown_member RPC stops the member and releases its tasks. Shutting down 'nothing' is meaningless, so the client rejects it up front.
Source
Thrown at app/src/services/api/agentTeamApi.ts:266
if (!teamId || !taskId || !memberId) {
throw new Error('agentTeamApi.completeTask: teamId, taskId and memberId are required');
}
log('completeTask teamId=%s taskId=%s requireEvidence=%o', teamId, taskId, requireEvidence);
const response = await callCoreRpc<{ result: CompletionOutcome }>({
method: 'openhuman.agent_team_complete_task',
params: { teamId, taskId, memberId, evidence, requireEvidence },
});
log('completeTask kind=%s', response.result.kind);
return response.result;
},
/**
* Stop a member and release any task it is actively working on back to `todo`.
* Returns the stopped member plus the ids that were released.
*/
shutdownMember: async (teamId: string, memberId: string): Promise<MemberShutdown> => {
if (!teamId || !memberId) {
throw new Error('agentTeamApi.shutdownMember: teamId and memberId are required');
}
log('shutdownMember teamId=%s memberId=%s', teamId, memberId);
const response = await callCoreRpc<{ result: MemberShutdown }>({
method: 'openhuman.agent_team_shutdown_member',
params: { teamId, memberId },
});
log('shutdownMember released=%d', response.result.releasedTaskIds.length);
return response.result;
},
/**
* Send a message to a named teammate (or broadcast when `toMemberId` is
* omitted). `fromMemberId` is omitted for a lead/user-originated message — the
* core stores it with `from = "lead"`. Returns the appended message event.
*/
messageMember: async (params: {
teamId: string;
toMemberId?: string;View on GitHub (pinned to a221052e0d)
Solutions
- Derive both ids from the same source-of-truth object (the member row) right at call time
- Disable the stop control until the member row (with teamId) is loaded
- If the member may already be gone, treat a missing id as a no-op in the UI instead of calling
Example fix
// before
onClick={() => agentTeamApi.shutdownMember(teamId, member?.id ?? '')}
// after
onClick={() => {
if (!teamId || !member?.id) return;
agentTeamApi.shutdownMember(teamId, member.id).catch(notify);
}} Defensive patterns
Strategy: validation
Validate before calling
const canShutdown = typeof teamId === 'string' && teamId !== '' && typeof memberId === 'string' && memberId !== ''; if (canShutdown) await agentTeamApi.shutdownMember(teamId, memberId);
Type guard
const hasBothIds = (t: unknown, m: unknown): t is string & { memberId: string } => false; // prefer explicit checks
const ok = (v: unknown): v is string => typeof v === 'string' && v.length > 0; Try / catch
try { await agentTeamApi.shutdownMember(teamId, memberId); }
catch (e) { if (String(e.message).includes('required')) refreshMembers(); else throw e; } Prevention
- Bind row actions to the full member row captured at render, not stale closures
- Treat a missing member row as 'already gone' and refresh the list
- Disable destructive controls during skeleton/loading states
When it happens
Trigger: Calling shutdownMember('', memberId) or shutdownMember(teamId, '') — e.g. a stop button wired to a member card whose id prop is missing, or the team context not yet loaded.
Common situations: Row actions rendered from sparse data; the member already removed from the list by the time the handler runs (stale closure holding empty id); optional-chained state defaulting to undefined.
Related errors
- agentTeamApi.get: teamId is required
- agentTeamApi.listMessages: teamId is required
- agentTeamApi.completeTask: teamId, taskId and memberId are r
- agentTeamApi.messageMember: teamId is required
- agentTeamApi.startMember: teamId and memberId are required
AI-assisted analysis of tinyhumansai/openhuman@a221052e0d (2026-08-16).
Data as JSON: /api/errors/67b48ce241da7ed3.
Report an issue: GitHub.