tinyhumansai/openhuman · error
agentTeamApi.listMessages: teamId is required
Error message
agentTeamApi.listMessages: teamId is required
What it means
Guard inside agentTeamApi.listMessages: the team id must be a non-empty string before the openhuman.agent_team_list_messages RPC is issued. The same call also runs assertPositiveInt on the optional limit, so a bad limit surfaces as the 'must be a positive integer' error instead.
Source
Thrown at app/src/services/api/agentTeamApi.ts:215
*/
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);
const response = await callCoreRpc<{ messages?: RawRunEvent[] }>({
method: 'openhuman.agent_team_list_messages',
params: limit === undefined ? { teamId } : { teamId, limit },
});
const messages = (response.messages ?? []).map(event => ({
runId: event.runId,
sequence: event.sequence,
eventType: event.eventType,
payload: readMessagePayload(event.payload),
timestamp: event.timestamp,
}));
log('listMessages received=%d', messages.length);
return messages;
},
/**View on GitHub (pinned to a221052e0d)
Solutions
- Gate the fetch on a truthy teamId in the component (skip or show empty state)
- Initialize team-dependent state to null/undefined, not '', and check it before calling
- Re-derive the id from the route/store right before the call rather than caching it in local state
Example fix
// before const msgs = await agentTeamApi.listMessages(teamId ?? ''); // after if (!teamId) return []; const msgs = await agentTeamApi.listMessages(teamId);
Defensive patterns
Strategy: validation
Validate before calling
if (typeof teamId === 'string' && teamId && Number.isInteger(limit ?? 1)) {
const msgs = await agentTeamApi.listMessages(teamId, limit);
} Type guard
const isNonEmptyString = (v: unknown): v is string => typeof v === 'string' && v.length > 0;
Try / catch
try { const msgs = await agentTeamApi.listMessages(teamId, limit); }
catch (e) { if (String(e.message).includes('teamId is required')) return []; else throw e; } Prevention
- Skip message-pane queries until the team context is resolved
- Keep limit clamping in one pagination helper
- Reset message state when the selected team id clears
When it happens
Trigger: Calling listMessages('') or listMessages(someUndefinedId) — e.g. a message pane mounted before the team is chosen, or a teamId prop that defaults to empty string.
Common situations: Chat/transcript components that load in parallel with the team selector; destructuring teamId from an object where the key is absent; race where the team is deleted while the view is open and state resets to ''.
Related errors
- agentTeamApi.get: 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/0206a67440db11f5.
Report an issue: GitHub.