Segment Effort Ids exceed JavaScript MAX_SAFE_INTEGER get truncated

52 views
Skip to first unread message

Mark Stosberg

unread,
Feb 17, 2022, 8:43:11 AM2/17/22
to Strava API
Hello,

I maintain the `node-strava-v3` library. Through a bug report, I learned that some segment effort IDs are very large numbers, larger than JavaScripts MAX_SAFE_INTEGER value. This is causing the values to get truncated during parsing and bugs result.  

Here's an illustration:

2922283800928553000 <- What node-strava-v3 returns for a segment effort ID 
2922283800928553202 <- What a direct API call with Curl returns for the same 
9007199254740991 <- For reference, the max Int size in Javascript

If Strava wants to support languages with similar "max int" values, returning these IDs as a string instead of a number could resolve the issue.

         Mark

Jan M.

unread,
Feb 17, 2022, 2:05:48 PM2/17/22
to Strava API
Or these languages with not long enough integers should tread the id as string

Chris Pointon

unread,
Feb 17, 2022, 4:00:23 PM2/17/22
to Jan M., Strava API
Node has supported 64-bit BigInt since v10. There is a BigInt-compatible JSON library here: https://www.npmjs.com/package/json-bigint

Earlier versions of Node can use this workaround:
  // Fix int wraparound
  const MAX_INT32 = Math.pow( 2, 31 ) - 1;
  if(Number.isInteger(data.id*1) && ((data.id * 1) < 0)) {
    data.id = (data.id*1)+(2 * (MAX_INT32 + 1));
  }

This'll work until Strava gets to 53 bits (limit that Number can handle, or Number.MAX_SAFE_INTEGER) - hopefully long enough away that we won't have to worry about it!

--
You received this message because you are subscribed to the Google Groups "Strava API" group.
To unsubscribe from this group and stop receiving emails from it, send an email to strava-api+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/strava-api/7796e795-7c2f-4b94-a6b5-aece92528c7bn%40googlegroups.com.

Chris Pointon

unread,
Feb 17, 2022, 4:03:42 PM2/17/22
to Jan M., Strava API
Just re-read Mark's post. Apparently we got to MAX_SAFE_INTEGER sooner than I thought! I should pay closer attention...

Daniel D.

unread,
Feb 19, 2022, 10:23:28 AM2/19/22
to Jan M., Strava API
I opened https://github.com/dblock/strava-ruby-client/issues/49 for the ruby client, would appreciate it if someone could add a unit test and document what happens in those cases.

--
You received this message because you are subscribed to the Google Groups "Strava API" group.
To unsubscribe from this group and stop receiving emails from it, send an email to strava-api+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/strava-api/7796e795-7c2f-4b94-a6b5-aece92528c7bn%40googlegroups.com.


--

Mark Stosberg

unread,
Feb 19, 2022, 11:08:00 AM2/19/22
to Strava API
The way that Twitter and Cisco handle this with their APIs is to return such large numbers as strings. See here:


Consider how these IDs are being used-- you are typically not doing math on them, you are storing them in database.

Jan M.

unread,
Feb 19, 2022, 7:17:36 PM2/19/22
to Strava API
The only problem with string representations could be sorting by the id, as higher numbers can be alphabetically lower than smaller numbers. But there aren't much use cases for sorting these ids, so maybe strings aren't in any way restricting.

Mark Stosberg

unread,
Feb 21, 2022, 9:50:27 AM2/21/22
to Strava API
A common use would be inserting the the IDs into the database of a web app. With PostgreSQL for example, if you try to insert a number as a string, it will be silently cast to a number. 

So for the common case of inserting the IDs into a database, it doesn't matter if they are represented as a string or a number in the JSON returned by the API. 

Below I show that inserting the value of 1 as a number and a string in PostgreSQL produces the same result.

postgres=# create table t (a int);
CREATE TABLE
postgres=# insert into t ("a") values (1);
INSERT 0 1
postgres=# insert into t ("a") values ('1');
INSERT 0 1
postgres=# select * from t;
 a
---
 1
 1
(2 rows)


Reply all
Reply to author
Forward
0 new messages