From c12c6b4e5f596ae8ca4f0a0aec2e1fe53217c615 Mon Sep 17 00:00:00 2001 From: Swifty Date: Fri, 6 Feb 2026 16:06:28 +0100 Subject: [PATCH] fix(backend): Auto-fork marketplace agent on first save to fix "Graph not found" error When a user adds a marketplace agent to their library and tries to save edits, the update_graph endpoint returned 404 because the graph is owned by the original creator. Now, if the user has the graph in their library but doesn't own it, a fork is automatically created with their edits applied, new IDs assigned, and a new library agent entry created. --- .../backend/backend/api/features/v1.py | 40 ++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/autogpt_platform/backend/backend/api/features/v1.py b/autogpt_platform/backend/backend/api/features/v1.py index a8610702cc..33f8cf6d83 100644 --- a/autogpt_platform/backend/backend/api/features/v1.py +++ b/autogpt_platform/backend/backend/api/features/v1.py @@ -7,6 +7,7 @@ from collections import defaultdict from datetime import datetime, timezone from typing import Annotated, Any, Sequence, get_args +import prisma.models import pydantic import stripe from autogpt_libs.auth import get_user_id, requires_user @@ -827,7 +828,44 @@ async def update_graph( existing_versions = await graph_db.get_graph_all_versions(graph_id, user_id=user_id) if not existing_versions: - raise HTTPException(404, detail=f"Graph #{graph_id} not found") + # User doesn't own this graph -- check if they have it in their library + # (e.g. added from the marketplace). If so, fork it with their edits applied. + library_agent = await prisma.models.LibraryAgent.prisma().find_first( + where={ + "userId": user_id, + "agentGraphId": graph_id, + "isDeleted": False, + } + ) + if not library_agent: + raise HTTPException(404, detail=f"Graph #{graph_id} not found") + + # Fork: apply the user's edits to a new user-owned graph + graph.version = 1 + graph.is_active = True + forked = graph_db.make_graph_model(graph, user_id) + forked.forked_from_id = graph_id + forked.forked_from_version = library_agent.agentGraphVersion + forked.reassign_ids(user_id=user_id, reassign_graph_id=True) + forked.validate_graph(for_run=False) + + new_graph_version = await graph_db.create_graph(forked, user_id=user_id) + new_graph_version = await on_graph_activate(new_graph_version, user_id=user_id) + await graph_db.set_graph_active_version( + graph_id=new_graph_version.id, + version=new_graph_version.version, + user_id=user_id, + ) + await library_db.create_library_agent(new_graph_version, user_id) + + new_graph_with_subgraphs = await graph_db.get_graph( + new_graph_version.id, + new_graph_version.version, + user_id=user_id, + include_subgraphs=True, + ) + assert new_graph_with_subgraphs + return new_graph_with_subgraphs graph.version = max(g.version for g in existing_versions) + 1 current_active_version = next((v for v in existing_versions if v.is_active), None)