This is an automated email from the ASF dual-hosted git repository.

klesh pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-devlake.git


The following commit(s) were added to refs/heads/main by this push:
     new 4ac2c4256 fix(bitbucket): handle API errors in workspace listing and 
guard empty pipelineId (#8885)
4ac2c4256 is described below

commit 4ac2c4256a9f015e6d13d43b2e287ab518c8417d
Author: bujjibabukatta <[email protected]>
AuthorDate: Sat May 30 01:27:01 2026 -0400

    fix(bitbucket): handle API errors in workspace listing and guard empty 
pipelineId (#8885)
    
    - Add HTTP status code check in listBitbucketWorkspaces, mirroring
      the existing check in listBitbucketRepos. A non-2xx Bitbucket response
      was silently unmarshalled as an empty WorkspaceResponse, causing the
      UI to show No data to select with no error surfaced to the user.
    
    - Guard against calling the pipeline subtasks API with an empty
      pipelineId in card.tsx and step-4.tsx. The record is initialised
      with pipelineId="" in step-2 before a pipeline has been triggered,
      causing the frontend to issue GET /pipelines//subtasks and receive
      a 400 invalid pipeline ID format error from the backend.
    
    Fixes #8868
---
 backend/plugins/bitbucket/api/remote_api.go      | 9 +++++++++
 config-ui/src/routes/onboard/components/card.tsx | 4 ++--
 config-ui/src/routes/onboard/step-4.tsx          | 5 ++++-
 3 files changed, 15 insertions(+), 3 deletions(-)

diff --git a/backend/plugins/bitbucket/api/remote_api.go 
b/backend/plugins/bitbucket/api/remote_api.go
index 2da3f7ab6..211901ec3 100644
--- a/backend/plugins/bitbucket/api/remote_api.go
+++ b/backend/plugins/bitbucket/api/remote_api.go
@@ -80,6 +80,15 @@ func listBitbucketWorkspaces(
        if err != nil {
                return
        }
+       if res.StatusCode > 299 {
+               body, e := io.ReadAll(res.Body)
+               if e != nil {
+                       err = errors.BadInput.Wrap(e, "failed to read response 
body")
+                       return
+               }
+               err = errors.HttpStatus(res.StatusCode).New(string(body))
+               return
+       }
 
        resBody := &models.WorkspaceResponse{}
        err = api.UnmarshalResponse(res, resBody)
diff --git a/config-ui/src/routes/onboard/components/card.tsx 
b/config-ui/src/routes/onboard/components/card.tsx
index d2250573d..2d45ffe3e 100644
--- a/config-ui/src/routes/onboard/components/card.tsx
+++ b/config-ui/src/routes/onboard/components/card.tsx
@@ -49,11 +49,11 @@ export const OnboardCard = ({ style }: Props) => {
 
   const tasksRes = useAutoRefresh(
     async () => {
-      if ((data && data.done) || !record) {
+      if ((data && data.done) || !record || !record.pipelineId) {
         return;
       }
 
-      return await API.pipeline.subTasks(record?.pipelineId as string);
+      return await API.pipeline.subTasks(record.pipelineId as string);
     },
     [record],
     {
diff --git a/config-ui/src/routes/onboard/step-4.tsx 
b/config-ui/src/routes/onboard/step-4.tsx
index 569ed0f3d..eb6eb44eb 100644
--- a/config-ui/src/routes/onboard/step-4.tsx
+++ b/config-ui/src/routes/onboard/step-4.tsx
@@ -112,7 +112,10 @@ export const Step4 = () => {
 
   const { data } = useAutoRefresh(
     async () => {
-      return await API.pipeline.subTasks(record?.pipelineId as string);
+      if (!record?.pipelineId) {
+        return;
+      }
+      return await API.pipeline.subTasks(record.pipelineId as string);
     },
     [record],
     {

Reply via email to