{"record":{"id":"5a1a10b0e07ad7d6","repo":"tinyhumansai/openhuman","slug":"agentteamapi-messagemember-teamid-is-required","errorCode":null,"errorMessage":"agentTeamApi.messageMember: teamId is required","messagePattern":"agentTeamApi\\.messageMember: teamId is required","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"app/src/services/api/agentTeamApi.ts","lineNumber":290,"sourceCode":"    });\n    log('shutdownMember released=%d', response.result.releasedTaskIds.length);\n    return response.result;\n  },\n\n  /**\n   * Send a message to a named teammate (or broadcast when `toMemberId` is\n   * omitted). `fromMemberId` is omitted for a lead/user-originated message — the\n   * core stores it with `from = \"lead\"`. Returns the appended message event.\n   */\n  messageMember: async (params: {\n    teamId: string;\n    toMemberId?: string;\n    fromMemberId?: string;\n    content: string;\n    visibility?: string;\n  }): Promise<TeamMessage> => {\n    const { teamId, toMemberId, fromMemberId, content, visibility } = params;\n    if (!teamId) throw new Error('agentTeamApi.messageMember: teamId is required');\n    if (!content.trim()) throw new Error('agentTeamApi.messageMember: content is required');\n    log('messageMember teamId=%s to=%o from=%o', teamId, toMemberId, fromMemberId);\n    const response = await callCoreRpc<{ message: RawRunEvent }>({\n      method: 'openhuman.agent_team_message_member',\n      params: {\n        teamId,\n        content,\n        ...(fromMemberId ? { fromMemberId } : {}),\n        ...(toMemberId ? { toMemberId } : {}),\n        ...(visibility ? { visibility } : {}),\n      },\n    });\n    const event = response.message;\n    return {\n      runId: event.runId,\n      sequence: event.sequence,\n      eventType: event.eventType,\n      payload: readMessagePayload(event.payload),","sourceCodeStart":272,"sourceCodeEnd":308,"githubUrl":"https://github.com/tinyhumansai/openhuman/blob/a221052e0df5b1f7598fceba7329fd1af95d6699/app/src/services/api/agentTeamApi.ts#L272-L308","documentation":"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.)","triggerScenarios":"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.","commonSituations":"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.","solutions":["Render or enable the composer only when a team id is present","Pass teamId from the route/store at submit time rather than from a prop that may lag","If the team was deleted mid-session, clear the composer state and show an explicit empty state"],"exampleFix":"// before\nconst send = (content: string) => agentTeamApi.messageMember({ teamId, content });\n\n// after\nconst send = (content: string) => {\n  if (!teamId) { setNotice('No team selected'); return; }\n  return agentTeamApi.messageMember({ teamId, content });\n};","handlingStrategy":"validation","validationCode":"const canSend = typeof teamId === 'string' && teamId !== '' && content.trim().length > 0;\nif (canSend) await agentTeamApi.messageMember({ teamId, content });","typeGuard":"const isNonEmptyString = (v: unknown): v is string => typeof v === 'string' && v.length > 0;","tryCatchPattern":"try { await agentTeamApi.messageMember({ teamId, content }); }\ncatch (e) { if (String(e.message).includes('teamId is required')) showNoTeamNotice(); else throw e; }","preventionTips":["Mount the composer only inside a resolved team context","Clear composer state when the team is deleted or deselected","Validate trimmed content at the UI boundary too (sibling guard exists)"],"tags":["validation","agent-teams","required-field"],"backgroundTag":null,"analyzedSha":"a221052e0df5b1f7598fceba7329fd1af95d6699","analyzedAt":"2026-08-16T12:47:06.542Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}