Invoke function calls duplicating (call function once, runs twice)

Hello all,

I am struggling with a weird issue on the backend of my UI kit global page module application. My goal is to create a new project with the kanban template, then change the statuses of the project to a custom status list of my own choosing. I want to make a button that creates the new project and then edits the project using jira REST API calls. But my invocation is behaving as follows:

  • if there is a bad request, the function is called only 1 time
  • if request is good, it is called 2 times in succession, causing the second invocation to throw a conflicting task (error code 500) error
  • Even though one of the 2 requests to make a project works, I get {size: 0, timeout: 0} when i log the output. Almost seems like the await function is not actually waiting for the function to complete, which in turn is causing my create statuses function to fail as well

The issue is not my useState hooks causing a re-render. I checked this and can confirm nothing is being re-rendered in this case.

Why is my invocation being called twice, and why am I getting an empty json response even for successful API calls?

Frontend function

const fetchData = async () => {
    const project = await invoke('project');
    console.log(project);//always returns {size: 0, timeout: 0}
    console.log(project.id);//always returns undefined
};

Frontend button component

 <Button shouldFitContainer onClick={async() => { //tried calling synchronously as well. 
            await fetchData()
          }}>make new project</Button>

Resolver function

resolver.define('makeProject', async ({ payload }) => {

  var bodyData = `{
    "key": "ECV",
    "leadAccountId": "557058:0867a421-a9ee-4659-801a-bc0ee4a4487e",
    "name": "Engineering Test23",
    "projectTemplateKey": "com.atlassian.jira-core-project-templates:jira-core-simplified-project-management",
    "projectTypeKey": "business"
  }`;

  try {
    console.log('inside the resolver')

    const response = await api.asUser().requestJira(route`/rest/api/3/project`, {
      method: 'POST',
      headers: {
        'Accept': 'application/json',
        'Content-Type': 'application/json'
      },
      body: bodyData
    });

    if (response.ok) {
      console.log('Project created successfully.');
    } else {
      const errorData = await response.json();
      console.error(`Failed to create project: ${response.status} ${response.statusText}`, errorData);
    }
    return response
  } catch (error) {
    console.error('Error creating project:', error);
    return null
  }
})

I haven’t played with creating a project through the api, but maybe try adding an await to the console logs. (e.g., console.log(await project);)? Could be it is logging the promise?

Or maybe try as non-async with an invoke.then()? Anecdotally, I’ve had better luck with following this in the new UI Kit.

const fetchData = () => {
  invoke('project').then((response) => {
    console.log(response);
    }
  };

Regarding duplicate invocations, I’m not sure, but I feel like a saw in a thread at some point that invocations are run twice from the development environment, but only be once from production. I don’t recall a rationale, or if that was just a known issue. I also couldn’t quickly find the thread again. Could it also have something to do with the console.logs and the project promise? The invoke.then() or adding awaits might also solve this?

Using “.then()” did not fix the issue for me, but returning “await response.json()” in resolver rather than just the response caused my await functions in the frontend to actually wait as intended and allowed me to properly log the response.

However, I can still see in my forge tunnel that the invocation happens twice, and that only one of the API calls works. Does not seem to be impacting my functionality for now, but I could definitely see this impacting my code in the future as I call the API more frequently…

Interesting. Glad you were able to move forward.

I just checked while tunneling and I currently am only seeing single invocations on the backend for my app. Do you happen to have any React on the front end that could be refreshing and triggering the invoke before it completes? Maybe add a frontend log just before the invoke to see if it is being called more than once?

These are my current forge dependency versions incase something was fixed along the way.

+-- @forge/api@5.0.0
+-- @forge/bridge@4.4.0
+-- @forge/cli@10.13.6
+-- @forge/react@10.11.0
+-- @forge/resolver@1.6.6