diff --git a/autogpt_platform/backend/backend/data/graph.py b/autogpt_platform/backend/backend/data/graph.py index 759a303c4b..3340716da8 100644 --- a/autogpt_platform/backend/backend/data/graph.py +++ b/autogpt_platform/backend/backend/data/graph.py @@ -683,7 +683,7 @@ class GraphModel(Graph, GraphMeta): continue for key, value in node.input_default.items(): if isinstance(value, dict) and "_credentials_id" in value: - value["_credentials_id"] = None + del value["_credentials_id"] def validate_graph( self, diff --git a/autogpt_platform/backend/backend/data/graph_test.py b/autogpt_platform/backend/backend/data/graph_test.py index 066cd3a3de..ff49db531e 100644 --- a/autogpt_platform/backend/backend/data/graph_test.py +++ b/autogpt_platform/backend/backend/data/graph_test.py @@ -560,8 +560,9 @@ def test_reassign_ids_clears_credentials_id(): GraphModel._reassign_ids(graph, user_id="new-user", graph_id_map={}) - # _credentials_id should be cleared - assert graph.nodes[0].input_default["spreadsheet"]["_credentials_id"] is None + # _credentials_id key should be removed (not set to None) so that + # _acquire_auto_credentials correctly errors instead of treating it as chained data + assert "_credentials_id" not in graph.nodes[0].input_default["spreadsheet"] def test_reassign_ids_preserves_non_credential_fields(): @@ -668,8 +669,8 @@ def test_reassign_ids_handles_multiple_credential_fields(): GraphModel._reassign_ids(graph, user_id="new-user", graph_id_map={}) - assert graph.nodes[0].input_default["spreadsheet"]["_credentials_id"] is None - assert graph.nodes[0].input_default["doc_file"]["_credentials_id"] is None + assert "_credentials_id" not in graph.nodes[0].input_default["spreadsheet"] + assert "_credentials_id" not in graph.nodes[0].input_default["doc_file"] assert graph.nodes[0].input_default["plain_input"] == "not a dict" diff --git a/autogpt_platform/backend/backend/executor/utils.py b/autogpt_platform/backend/backend/executor/utils.py index e3d24be556..ffccd125b9 100644 --- a/autogpt_platform/backend/backend/executor/utils.py +++ b/autogpt_platform/backend/backend/executor/utils.py @@ -353,6 +353,15 @@ async def _validate_node_input_credentials( ) if field_value and isinstance(field_value, dict): + if "_credentials_id" not in field_value: + # Key removed (e.g., on fork) — needs re-auth + has_missing_credentials = True + credential_errors[node.id][field_name] = ( + "Authentication missing for the selected file. " + "Please re-select the file to authenticate with " + "your own account." + ) + continue cred_id = field_value.get("_credentials_id") if cred_id and isinstance(cred_id, str): try: @@ -367,9 +376,9 @@ async def _validate_node_input_credentials( if not creds: has_missing_credentials = True credential_errors[node.id][field_name] = ( - "The saved Google credentials are not available " + "The saved credentials are not available " "for your account. Please re-select the file to " - "authenticate with your own Google account." + "authenticate with your own account." ) # If node has optional credentials and any are missing, mark for skipping