Change notice - Connect - contentId value returned by AP.navigator.getLocation value changing from number to string

What is changing?

The context.contentId property of AP.navigator.getLocation (see Navigator.getLocation) is changing from a number to a string . This is because Confluence contentIds can be up to 64 bits (a long ), which is larger than what can be represented in a JavaScript number (which maxes out at 53 bits of integer precision, see Number - JavaScript | MDN.

Old value - number

AP.navigator.getLocation(function (location) {
// location will be:
   {
     "target": "contentview",
     "context": {
       "contentId": 1234, // <- old value is number
       "contentType": "page",
       "spaceKey": "DS"
     }
   }
});

New value - string

AP.navigator.getLocation(function (location) {
 // location will be:
   {
     "target": "contentview",
     "context": {
       "contentId": "1234", // <- new value is string
       "contentType": "page",
       "spaceKey": "DS"
     }
   }
});

Why is it changing?

We recently started seeing very large contentIds for certain customers, above normal limits that we’ve seen in the past. Our frontend not supporting large contentIds is a pre-existing bug, however it was rarely encountered in the past, until we started seeing more frequent usage of very large IDs. Any apps using contentId that cannot handle a 64 bit integer will not work correctly on pages with these very large IDs.

In practice, how this manifests is contentIds that are larger than Number.MAX_SAFE_INTEGER (eg 269528037047075906 ) will lose precision and cause the value to become incorrect, which can lead to either 404 errors, or referring to another existing but incorrect page, in any API calls using that contentId . To see this in action, enter this number in a JavaScript console:

> 269528037047075906
2269528037047075900

What do I need to do?

If you simply concatenate the provided contentId into a string for API calls in JavaScript, then you won’t need to do anything. Since JavaScript is relaxed about types, using a number or string is interchangeable in most scenarios where this contentId would be used.

However, if your app handles these contentIds in any other way, such as explicitly checking if they are numeric (eg contentId === 0 ), storing them in a database, or sending them to a backend running a strongly typed language, it could cause issues.

By when do I need to do it?

We have already started rolling out the change to a select few customers who are experiencing major issues as a result of not being able to use apps correctly with large Confluence IDs.

We will also begin rolling out this change to the developer first beta group starting today, so you can start testing this change works for your apps.

For general rollout, as we don’t anticipate widespread breakage for this change, and we want to expedite the fix for our customers facing issues, we are targeting a gradual production rollout starting 10 Jan 2022.

2 Likes

Hi @SamLeatherdale!

Will this change also be applied to other places (in the REST APIs and webhooks, specifically)? Many of us are using backends written in Node.js, which experiences the same behavior.

(Edit: I just saw that the REST APIs already use strings for contentIds, but webhooks don’t seem to do that)

I understand the issue that large contentIds pose, but this only somewhat backwards-compatible change in an API type seems abrupt. I agree that most Javascript code won’t encounter an issue here, but I still would have liked a backwards-compatible way of rolling out this change, especially if it’s being rolled out gradually (and with very little notice, to be honest).

As a possible solution, I remember the Twitter API just added a string field for their Tweet IDs at some point and are just sending both the number and string versions of the ID field (last time I checked, this was several years ago though, so take it with a grain of salt).

Maybe something like adding a field contentIdStr : string would be a solution that could also be added to all other APIs the webhooks in a backwards-compatible way so we can have a proper deprecation period.

Cheers,
Tobi

Hi @tobitheo, thanks for replying and sharing your concerns with us.

This is still an evolving issue and so the change may end up being applied in other places, I cannot provide a confirmation on that at this stage as I am from the Atlassian Connect JavaScript team.

If this change does need to be applied to the webhooks, we will definitely take your suggestion re: a new string field into account, thank you for providing it. As backends interacting with the API/webhooks could be in strongly typed languages, this would definitely be a more significant change than just changing it on the JavaScript frontend.

In regards to the short notice period, we have been evaluating the length of the notice period based on the customers that have been facing this issue and the likelihood of breakages for how this API is used. In this case adding a new string field didn’t seem necessary for the likelihood of issues, and would create more work by forcing all vendors to update their apps, rather than just a small affected portion.

We can extend this period or slow the rollout if these parameters change, ie if we find a better mitigation or vendors begin to face issues. We are also evaluating other ways to mitigate this issue internally. We have already enabled this change for the Confluence Vendor Beta group, so vendors can test this change with their apps.

Thanks again!

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.