{"record":{"id":"6937a71a5a7474bf","repo":"Significant-Gravitas/AutoGPT","slug":"expert-expert-id-not-found-6937a7","errorCode":null,"errorMessage":"Expert #{expert_id} not found.","messagePattern":"Expert #(.+?) not found\\.","errorType":"http","errorClass":"HTTPException","httpStatus":404,"severity":"error","filePath":"autogpt_platform/backend/backend/api/features/v1.py","lineNumber":2456,"sourceCode":"        )\n\n    # Use timezone from request if provided, otherwise fetch from user profile\n    if schedule_params.timezone:\n        user_timezone = schedule_params.timezone\n    else:\n        user = await get_user_by_id(user_id)\n        user_timezone = get_user_timezone_or_utc(user.timezone if user else None)\n\n    # Expert attribution: explicit expert_id must be an active expert owned\n    # by the caller; when omitted, a unique (user, graph) → expert match\n    # keeps attribution for schedules created through the generic UI.\n    expert_id = schedule_params.expert_id\n    if expert_id is not None:\n        expert = await experts_db.get_expert(\n            user_id, expert_id, include_workflows=False\n        )\n        if expert is None or expert.is_archived:\n            raise HTTPException(\n                status_code=404, detail=f\"Expert #{expert_id} not found.\"\n            )\n    else:\n        expert_id = await experts_db.resolve_expert_for_graph(user_id, graph_id)\n\n    result = await get_scheduler_client().add_execution_schedule(\n        user_id=user_id,\n        graph_id=graph_id,\n        graph_version=graph.version,\n        name=schedule_params.name,\n        cron=schedule_params.cron,\n        input_data=schedule_params.inputs,\n        input_credentials=schedule_params.credentials,\n        user_timezone=user_timezone,\n        organization_id=ctx.org_id,\n        team_id=ctx.team_id,\n        expert_id=expert_id,\n    )","sourceCodeStart":2438,"sourceCodeEnd":2474,"githubUrl":"https://github.com/Significant-Gravitas/AutoGPT/blob/9c8bb5550f446ba5d3046b78896578742495b3cf/autogpt_platform/backend/backend/api/features/v1.py#L2438-L2474","documentation":"Schedule-creation raises 404 when an explicit schedule_params.expert_id fails `experts_db.get_expert(user_id, expert_id)`: either the expert row doesn't exist for this user or `expert.is_archived` is true. This is attribution validation — every schedule must map to an active expert owned by the caller; when expert_id is omitted the endpoint instead auto-resolves via resolve_expert_for_graph and never takes this branch.","triggerScenarios":"POST /v1/schedules with expert_id in the body that is deleted/archived, belongs to another user, or is a stale ID kept in frontend state after the expert list changed.","commonSituations":"UI caching an expert picker selection after the expert was archived; scheduling from a saved form/config that pins an old expert_id; API scripts reusing expert IDs across accounts.","solutions":["Re-fetch the caller's active experts and re-submit with a current, non-archived expert_id.","Un-archive the expert if it should still receive attribution, or clear expert_id to let the endpoint auto-resolve the (user, graph) → expert match.","Ensure the expert belongs to the same user_id that authenticated the request."],"exampleFix":"// before\nawait api.createSchedule({graphId, expertId: savedExpertId, ...});\n// after — drop stale expert ids\nconst experts = await api.listExperts({archived: false});\nconst expert = experts.find(e => e.id === savedExpertId);\nawait api.createSchedule({graphId, expertId: expert?.id ?? undefined, ...});","handlingStrategy":"validation","validationCode":"const experts = await api.listExperts();\nconst active = experts.filter(e => !e.isArchived && e.userId === currentUserId);\nconst expertId = active.some(e => e.id === pickedId) ? pickedId : undefined;","typeGuard":"function isActiveOwnedExpert(e: ExpertDTO | undefined, userId: string): boolean {\n  return !!e && e.userId === userId && !e.isArchived;\n}","tryCatchPattern":"try {\n  await api.createSchedule({...params, expertId});\n} catch (e) {\n  if (e.status === 404 && 'expert_id' in payload) {\n    // re-fetch active experts and retry once without the stale id\n    return api.createSchedule({...payload, expertId: undefined});\n  }\n  throw e;\n}","preventionTips":["Source expert_id from a live (non-archived, owned) expert list at submit time.","Allow omitting expert_id so the backend auto-resolves attribution.","Invalidate cached expert picks when the expert list changes."],"tags":["http-404","schedules","expert-attribution","archived-entities"],"backgroundTag":null,"analyzedSha":"9c8bb5550f446ba5d3046b78896578742495b3cf","analyzedAt":"2026-08-14T17:17:21.957Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}