File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -623,7 +623,25 @@ def add_to_project(project_id: str, issue_id: str) -> str:
623623 }
624624 """
625625 data = _graphql (mutation , {"pid" : project_id , "cid" : issue_id })
626- return data ["addProjectV2ItemById" ]["item" ]["id" ]
626+ item = (data .get ("addProjectV2ItemById" ) or {}).get ("item" )
627+ if not item or not item .get ("id" ):
628+ raise RuntimeError (
629+ "Project API returned no item id when adding issue to project. "
630+ "Check token scopes and project access."
631+ )
632+ return item ["id" ]
633+
634+
635+ def _issue_node_id (issue : Dict [str , Any ]) -> Optional [str ]:
636+ """Return GraphQL node id for a REST issue payload if available."""
637+ node_id = issue .get ("node_id" )
638+ if isinstance (node_id , str ) and node_id .strip ():
639+ return node_id
640+ # Some payloads might already pass an ID-like value in 'id'.
641+ raw_id = issue .get ("id" )
642+ if isinstance (raw_id , str ) and raw_id .strip ():
643+ return raw_id
644+ return None
627645
628646
629647def _set_single_select (
@@ -668,7 +686,13 @@ def sync_to_project(
668686 fields : Dict [str , Any ],
669687 options : Dict [str , str ],
670688) -> None :
671- issue_id = issue ["id" ]
689+ issue_id = _issue_node_id (issue )
690+ if issue_id is None :
691+ print (
692+ f" ⚠ Skipping project sync for '{ task .title } ': issue payload "
693+ "does not include a GraphQL node id."
694+ )
695+ return
672696 status_opt = options .get (f"Status:{ task .project_status } " )
673697 priority_opt = options .get (f"Priority:{ task .project_priority } " )
674698
You can’t perform that action at this time.
0 commit comments