{"record":{"id":"36c478192d7ea222","repo":"tinyhumansai/openhuman","slug":"unknown-member-member-id","errorCode":null,"errorMessage":"unknown member: {member_id}","messagePattern":"unknown member: (.+?)","errorType":"validation","errorClass":"TeamError","httpStatus":null,"severity":"warning","filePath":"src/openhuman/agent/orchestration/agent_teams/ops.rs","lineNumber":149,"sourceCode":"    owner_member_id: Option<&str>,\n    depends_on: &[String],\n) -> Result<AgentTeamTask> {\n    log::debug!(\n        \"{LOG_PREFIX} assign_task.entry team={team_id} deps={}\",\n        depends_on.len()\n    );\n\n    let team = run_ledger::get_agent_team(&config.workspace_dir, team_id)?\n        .ok_or_else(|| anyhow!(\"unknown team: {team_id}\"))?;\n    let _ = team;\n\n    let existing = run_ledger::list_agent_team_tasks(&config.workspace_dir, team_id)?;\n    let task_id = format!(\"task-{}\", Uuid::new_v4().simple());\n\n    if let Some(owner) = owner_member_id {\n        let members = run_ledger::list_agent_team_members(&config.workspace_dir, team_id)?;\n        if !members.iter().any(|m| m.id == owner) {\n            return Err(anyhow!(TeamError::UnknownMember {\n                member_id: owner.to_string(),\n            }));\n        }\n    }\n\n    validate_dependencies(&task_id, depends_on, &existing)?;\n\n    let order_index = existing.len() as i64;\n    let task = run_ledger::upsert_agent_team_task(\n        &config.workspace_dir,\n        AgentTeamTaskUpsert {\n            id: task_id.clone(),\n            team_id: team_id.to_string(),\n            title: title.to_string(),\n            objective: objective.map(str::to_string),\n            status: AgentTeamTaskStatus::Todo,\n            owner_member_id: owner_member_id.map(str::to_string),\n            depends_on: depends_on.to_vec(),","sourceCodeStart":131,"sourceCodeEnd":167,"githubUrl":"https://github.com/tinyhumansai/openhuman/blob/a221052e0df5b1f7598fceba7329fd1af95d6699/src/openhuman/agent/orchestration/agent_teams/ops.rs#L131-L167","documentation":"Thrown by agent_teams assign_task when an owner_member_id is supplied that matches no member row in that team (checked via list_agent_team_members). It compares against member IDs — the generated row identifiers returned by creation, not the human-readable member names. Passing a member name, an id from another team, or a stale id after membership changes produces this error; the task insert is aborted.","triggerScenarios":"Setting owner_member_id to the member's name ('researcher') instead of its id ('m-...'); mixing ids across teams; a member removed/re-created so the old id no longer resolves.","commonSituations":"LLM filling owner from the roster it wrote in the prompt (names) rather than the create response (ids); maintaining task templates that hard-code old member ids.","solutions":["Fetch the team via agent_team_get and read each member's id field; use that exact id as owner_member_id","Omit owner_member_id to create an unassigned task and let members claim it","Regenerate any stored member ids after re-creating a team"],"exampleFix":"// before\n{\"team_id\":\"team-3f9a...\",\"owner_member_id\":\"researcher\",...} // -> unknown member: researcher\n// after: agent_team_get shows member id \"m-8c21...\"\n{\"team_id\":\"team-3f9a...\",\"owner_member_id\":\"m-8c21...\",...}","handlingStrategy":"validation","validationCode":"// Resolve owner to a real member id before assigning:\nlet view = tool_exec(\"agent_team_get\", json!({\"team_id\": tid})).await?;\nlet owner_id = view.members.iter().find(|m| m.name == owner_name)\n    .ok_or_else(|| anyhow!(\"no member named {owner_name}\"))?.id.clone();\ntool_exec(\"agent_team_assign_task\", json!({\"team_id\": tid, \"owner_member_id\": owner_id, /* ... */})).await","typeGuard":"fn member_id_in_team(view: &TeamView, member_id: &str) -> bool {\n    view.members.iter().any(|m| m.id == member_id)\n}","tryCatchPattern":"match tool_exec(\"agent_team_assign_task\", args).await {\n    Err(e) if e.to_string().contains(\"unknown member\") => {\n        let view = tool_exec(\"agent_team_get\", json!({\"team_id\": args[\"team_id\"]})).await?;\n        // map name->id from view.members and re-submit, or drop owner_member_id (unassigned task)\n        unimplemented!()\n    }\n    other => other,\n}","preventionTips":["owner_member_id takes the member ID (m-...), not the display name — read ids from agent_team_get","Prefer unassigned tasks + claim flow when ownership is uncertain","Regenerate stored member ids whenever a team is re-created"],"tags":["rust","agent-teams","not-found","validation","orchestration"],"backgroundTag":null,"analyzedSha":"a221052e0df5b1f7598fceba7329fd1af95d6699","analyzedAt":"2026-08-16T12:47:06.542Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}