tinyhumansai/openhuman · error

agentTeamApi.messageMember: teamId is required

Error message

agentTeamApi.messageMember: teamId is required

What it means

Guard inside agentTeamApi.messageMember: teamId must be a non-empty string before the openhuman.agent_team_message_member RPC appends a message event. (A sibling guard in the same function rejects blank content; this error is specifically the missing team id.)

Source

Thrown at app/src/services/api/agentTeamApi.ts:290

    });
    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;
    fromMemberId?: string;
    content: string;
    visibility?: string;
  }): Promise<TeamMessage> => {
    const { teamId, toMemberId, fromMemberId, content, visibility } = params;
    if (!teamId) throw new Error('agentTeamApi.messageMember: teamId is required');
    if (!content.trim()) throw new Error('agentTeamApi.messageMember: content is required');
    log('messageMember teamId=%s to=%o from=%o', teamId, toMemberId, fromMemberId);
    const response = await callCoreRpc<{ message: RawRunEvent }>({
      method: 'openhuman.agent_team_message_member',
      params: {
        teamId,
        content,
        ...(fromMemberId ? { fromMemberId } : {}),
        ...(toMemberId ? { toMemberId } : {}),
        ...(visibility ? { visibility } : {}),
      },
    });
    const event = response.message;
    return {
      runId: event.runId,
      sequence: event.sequence,
      eventType: event.eventType,
      payload: readMessagePayload(event.payload),

View on GitHub (pinned to a221052e0d)

Solutions

  1. Render or enable the composer only when a team id is present
  2. Pass teamId from the route/store at submit time rather than from a prop that may lag
  3. If the team was deleted mid-session, clear the composer state and show an explicit empty state

Example fix

// before
const send = (content: string) => agentTeamApi.messageMember({ teamId, content });

// after
const send = (content: string) => {
  if (!teamId) { setNotice('No team selected'); return; }
  return agentTeamApi.messageMember({ teamId, content });
};
Defensive patterns

Strategy: validation

Validate before calling

const canSend = typeof teamId === 'string' && teamId !== '' && content.trim().length > 0;
if (canSend) await agentTeamApi.messageMember({ teamId, content });

Type guard

const isNonEmptyString = (v: unknown): v is string => typeof v === 'string' && v.length > 0;

Try / catch

try { await agentTeamApi.messageMember({ teamId, content }); }
catch (e) { if (String(e.message).includes('teamId is required')) showNoTeamNotice(); else throw e; }

Prevention

When it happens

Trigger: Calling messageMember({ content }) without teamId, or with teamId: '' — e.g. a composer rendered outside a team context, or the team id not yet propagated via props/context when the user hits send.

Common situations: Shared composer component reused on a screen where teamId is optional and left empty; send handler firing before a context provider finishes loading; state reset to '' after team deletion while the composer stayed mounted.

Related errors


AI-assisted analysis of tinyhumansai/openhuman@a221052e0d (2026-08-16). Data as JSON: /api/errors/5a1a10b0e07ad7d6. Report an issue: GitHub.