tinyhumansai/openhuman · error
agentTeamApi.get: teamId is required
Error message
agentTeamApi.get: teamId is required
What it means
Guard inside agentTeamApi.get: the team id argument is checked for truthiness before issuing the openhuman.agent_team_get RPC. An empty/whitespace-free falsy id means the caller has no team reference and the request would be meaningless, so it throws immediately.
Source
Thrown at app/src/services/api/agentTeamApi.ts:199
*/
list: async (params: AgentTeamListParams = {}): Promise<AgentTeam[]> => {
assertPositiveInt(params.limit, 'limit');
log('list params=%o', params);
const response = await callCoreRpc<{ teams?: AgentTeam[]; count?: number }>({
method: 'openhuman.agent_team_list',
params,
});
const teams = response.teams ?? [];
log('list received teams=%d count=%o', teams.length, response.count);
return teams;
},
/**
* Fetch one team plus its members and tasks. Returns `null` when the id is
* unknown (the controller answers `{ team: null }`).
*/
get: async (teamId: string): Promise<TeamView | null> => {
if (!teamId) throw new Error('agentTeamApi.get: teamId is required');
log('get teamId=%s', teamId);
const response = await callCoreRpc<{ team: TeamView | null }>({
method: 'openhuman.agent_team_get',
params: { teamId },
});
log('get found=%o', response.team != null);
return response.team ?? null;
},
/**
* List a team's teammate messages in sequence order. Unwraps the
* `{ messages }` envelope and narrows each run-event payload to a typed
* {@link TeamMessagePayload}.
*/
listMessages: async (teamId: string, limit?: number): Promise<TeamMessage[]> => {
if (!teamId) throw new Error('agentTeamApi.listMessages: teamId is required');
assertPositiveInt(limit, 'limit');
log('listMessages teamId=%s limit=%o', teamId, limit);View on GitHub (pinned to a221052e0d)
Solutions
- Only call get() once a team id exists — gate the effect/handler on the id being non-empty
- Default the selector to skip the fetch: if (!teamId) return null instead of calling the API
- Fix the upstream state so the empty id never reaches this layer
Example fix
// before
useEffect(() => { agentTeamApi.get(selectedTeamId).then(setTeam); }, [selectedTeamId]);
// after
useEffect(() => {
if (!selectedTeamId) { setTeam(null); return; }
agentTeamApi.get(selectedTeamId).then(setTeam).catch(notify);
}, [selectedTeamId]); Defensive patterns
Strategy: validation
Validate before calling
const hasTeamId = (id: string | null | undefined): id is string => typeof id === 'string' && id.length > 0;
if (!hasTeamId(teamId)) { setTeam(null); } else { agentTeamApi.get(teamId).then(setTeam); } Type guard
const isNonEmptyString = (v: unknown): v is string => typeof v === 'string' && v.length > 0;
Try / catch
try { const team = await agentTeamApi.get(teamId); }
catch (e) { if (String(e.message).includes('teamId is required')) showEmptyState(); else throw e; } Prevention
- Initialize id state to null, not '', so falsy checks are natural
- Gate data-fetch effects on the id being truthy
- Type route params as string | undefined and check before use
When it happens
Trigger: Calling agentTeamApi.get(''), agentTeamApi.get(undefined as any), or get(id) where id came from an unset route param / unselected list item. Only a non-empty string reaches callCoreRpc.
Common situations: A detail panel rendered before a team is selected in the list; a route like /teams/:teamId mounted with no id; a store field still null on first render feeding get() directly.
Related errors
- 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
- agentTeamApi.startMember: teamId and memberId are required
AI-assisted analysis of tinyhumansai/openhuman@a221052e0d (2026-08-16).
Data as JSON: /api/errors/c59c1e1a52e1fdfa.
Report an issue: GitHub.