Asana is moving to string IDs [Updated with revised timeline]

Thanks all for your prompt responses!

@Joe_Trollo, that makes it very clear. I’m assuming the settings apply only for that session and for a new session, if I don’t send in the header, the behavior will fallback to default, i.e. receiving both integer and string IDs. Also, would you advice we wait till your implementation is 100% before performing any further tests?

If you set the headers on the client directly, they will apply to every request made with that client. If you pass them in the method call, they will apply only to that one request. Clearing the header from the client or not including them in the method call will then fall back to the default behavior, yes.

To be more explicit about the gap in our implementation: we have 100% coverage on read and write requests in the API (enabling this feature will hide numeric IDs on reads and reject numeric IDs on writes) but do not yet have support for requests that originate from within Asana (i.e., outgoing webhook payloads). If your app does not use webhooks, you can freely test the rest of the API, but we won’t be starting the clock for the deprecation until the entire API supports string IDs.

Got it. I’ve successfully tested switching the integer ids on an off - thanks!

Hi everyone! After a disappointingly large technical hurdle, we’re finally able to begin this deprecation! To recap:

  • This deprecation will operate under the name "string_ids" and can be enabled by sending an Asana-Enable: string_ids header in your requests
  • When this deprecation is enabled,
    • The API will not provide a numerical "id" field for any object in the response, and you will only receive the string "gid" field
    • The API will not accept numerical IDs in any part of the request
      • URLs and paths are already always strings and do not need to be changed
      • Form-encoded key-value pairs don’t have type information and are already always strings, so they do not need to be changed
      • JSON bodies do have type information, and you’ll need to change the fields in your request bodies from things like "projects": [123, 456] to "projects": ["123", "456"]
  • There are new settings to control the format of webhook bodies
    • The webhook objects themselves have an "always_use_string_ids" field on them which you can change to migrate individual webhooks into the new format
    • Each app in your developer console will have options for migrating the entire app as a whole (screenshots below)
    • Refer to the table in my previous post for specifics on how these two settings interact

Here’s what the app option will look like in the developer console:

On the matter of the timeline:

  • You can begin the deprecation starting today. The new options in the developer console will be gradually rolling out over the next week or so.
  • The “activation date” (the day on which string IDs become the default behavior) will be August 13th, 2019
  • The “end date” (the day on which string IDs become permanent) will be February 11th, 2020

As always, let us know if you have any questions about this deprecation. Because of the scope of this deprecation, we’ll be monitoring the situation closely as developers migrate their apps.

6 Likes

The new options in the developer console have now been rolled out to 100% of users.

4 Likes

Hello.

I am trying to send the header Asana-Enable: string_ids from the official PHP client library https://github.com/Asana/php-asana.

Can you provide an example on how this is done? Thank you very much.

Hello all, we have an important update to share about the timeline of this deprecation.

Because this deprecation affects literally every API request and webhook, there’s a risk that we will cause a large number of heavily-used apps to encounter errors for extended periods of time if we change the default behavior in an instant on the activation date. In fact, in the last month, nearly 7,000 apps with over 230,000 users have not opted in or out of the deprecation and will almost certainly break when the deprecation is activated on August 13th.

To mitigate this, we will make changes to the default behavior in three steps:

  • August 13th, 12:00 pm PDT — we will change the default behavior from inactive to active for five minutes, turning it back to inactive at 12:05 pm. This will cause errors for large, heavily-used apps and prompt their developers to begin investigations. By only staying enabled for five minutes, we ensure that these apps are not broken for several hours or several days while their developers learn about the deprecation and try to adjust for it. (Updating code and tests to use the deprecation framework and opt-out can take significant time for large apps with complex deployments.)
  • August 20th, 12:00 pm PDT — we will change the default behavior from inactive to active for one hour, turning it back to inactive at 1:00 pm. Assuming the largest apps were caught by the previous event, this will catch the next group of apps, such as those that may not make requests more than once per five minutes.
  • August 27th, 12:00 pm PDT — we will change the default behavior from inactive to active and keep it active. From this point on, old behavior will only be accessible through sending an Asana-Disable: string_ids header to opt-out.

Please let us know if you have any questions or concerns about this timeline.

1 Like

Wow. BUT maybe it won’t be quite that dire - perhaps (hopefully) other apps are in the same boat as Flowsana: because you started passing “gid” alongside “id” many months ago, I switched to relying on “gid” for my IDs a while back. That means that I’m compatible with the new string-ID model (except for webhooks) without having to opt in or out.

"except for webhooks"
Well, OK, true, my hopeful optimism doesn’t apply to webhooks - for apps that use those and didn’t opt in or out, their webhook code will break on August 13th. (I just updated mine today, will be testing it this coming week and putting it into production next weekend.)

And I’ve converted Asana2Go this past weekend so your outstanding list is down to 6,999 now!

Thanks,

Larry

2 Likes

Hello all, I have a last-minute update about today’s scheduled “bump.” Because we are currently experiencing downtime, we will not be changing the default behavior today. We will instead be having the bump tomorrow, August 14th from 12:00 pm to 12:05 pm PDT. Sorry for the sudden change, but we are concerned that developers may attribute string-ID-related errors as fallout from the downtime and thus ignore it.

3 Likes
  • August 27th, 12:00 pm PDT — we will change the default behavior from inactive to active and keep it active . From this point on, old behavior will only be accessible through sending an Asana-Disable: string_ids header to opt-out.

Hi, I currently interface with the Asana API through the Ruby gem (using v0.9.2). With the recent transition of the string_ids change to active, we’ve started to get invalid request errors, which is expected.

We were upgrading from v0.6.0 and the previous error message was:

Error: #<Asana::Errors::InvalidRequest: tag: Not a valid GID type: number>

after upgrading the gem we now get

Error: #<Asana::Errors::InvalidRequest: task: Not a Long: >

I’ve looked into temporarily disabling the string id change so we can migrate on our end, by adding the Asana-Disable header:

@client = ::Asana::Client.new do |c|
  c.default_headers({ 'Asana-Disable' => 'string_ids' })
end

While the deprecation warnings have been suppressed, we’re not seeing the error going away, which might suggest the disabling isn’t coming through.

Would you be able to help me verify if Asana-Disable for this feature is working (or that’s it’s intended that it can’t be disabled anymore) and will continue until the Feb 2020 deadline? Thanks!

1 Like

Making a massively breaking change like this just before a long weekend is not a great plan, IMHO.

Said a guy who’s going to get to do a lot of manual labor since php-asana no longer seems to function, and sorting out how to make it work again is a task I’m giving up on.

@ctam—Sorry for the trouble there. I’m not sure what’s wrong but I’ll pass this along to the engineer responsible for the Ruby client library who will investigate.

@Adam_Lambert—I’m sorry that this deprecation caught you off-guard. We tried our best to communicate these changes through a number of channels over the past year, but unfortunately we weren’t able to reach everyone. If you can describe the issue you’re having with the PHP client library here, or file an issue in the GitHub repository, one of our engineers can investigate what’s going wrong.

1 Like

I finally got it working by adding a hack to send the Asana-Disable: string_ids header. I am still having no idea what needs to be done to make the php-asana (the official one) client use the string based id’s. I hope/assume whoever works on the php-asana library is aware that it’s broken and will be working to fix it before the Asana-Disable hack goes away.

And to be clear, my beef was less that a change had to be made, and more that it got made right before a long weekend.

Hello all, I have a rather unfortunate update.

Sometime between when we did all the engineering and testing work for string IDs about 10 months ago and when we activated the string ID change this past month, we introduced a bug in our configuration. This impact of this bug is that only some routes and features of our API are excluding numeric IDs by default. In particular: webhooks, event streams, and PUT/POST routes now exclude numeric IDs from their responses. Meanwhile, the rest of our API is still returning the id field by default if you haven’t opted out of the deprecation.

This means that we still have half of this deprecation we need to activate, and it actually accounts for a lot more than half of the API and its traffic. If you are not using the deprecation headers, your app is operating in a half-old, half-new world and there is still a very large possibility that it will break with the next activation. Once again, to mitigate the impact, we will “bump” the API for a short period of time to help apps discover incompatibilities without breaking them for too long. The schedule for the remaining rollout is as follows:

  • September 17th, 10:00 am PDT — we will change the default behavior from inactive to active for two hours, turning it back to inactive at 12:00 pm. We will be monitoring the impact from this “bump” through a number of channels. Depending on the magnitude of the impact, we may postpone the final activation.
  • September 24th, 10:00 am PDT — we will change the default behavior from inactive to active and keep it active. From this point on, old behavior will only be accessible by sending an Asana-Disable: string_ids header to temporarily opt-out.

To summarize, you will fall into one of these three categories and should take the recommended action:

  • If you have already opted in or out by passing in deprecation headers, you have no further action to take.
  • If you have changed your code to leverage string GIDs but are not sending headers, please check that you have applied the changes to your code using our read endpoints as these have still been providing numeric IDs.
  • If you haven’t yet taken action on this deprecation, your app may already be malfunctioning, so please modify your app to use string GIDs or delay the deprecation by opting out by sending an Asana-Disable: string_ids header.

Some background about the bug and its discovery

Background: The API has a “live” configuration that, when changed, will immediately be reflected in the active API deployments. In this configuration, we list out all the ongoing deprecations and whether they are enabled by default. This is actually a list, too, and not a mapping. These are the settings we change on the start, activation, and end dates for deprecations. There is also a “base” configuration that is used as a fallback for things not specified in the live configuration. The final configuration is determined by taking the base configuration and “merging” it with the live configuration, overwriting appropriate keys.

Additionally, those of you who have been around for a while may recall that we rebuilt our API to improve performance. Due to internal technical limitations, we unfortunately have to maintain both the new and old systems. The old handles webhooks, event streams, and writes of data, while the new handles reading data.

Bug: The old system (which was correctly activated) read default values for our deprecations, and then completely replaced the list of settings with the live configuration. The new system read the default values, and then extended that list with the live configuration. This led to a final configuration that was akin to deprecations: ["something else", "string IDs are off by default", "another thing", "string IDs are on by default"]. (We don’t actually use a list of strings like this—we’re not monsters!) When we later used this list to determine what the default behavior should be, we took the first matching setting in the list, which indicated that string IDs should not be activated.

Discovery: I was making some manual API requests to debug a script I was creating, and was not bothering to pass any deprecation headers. I then noticed in the responses that the id field was still being included, which kicked off the investigation.

Remediation: We will be changing our configuration parsing to assert that no deprecation appears twice in the final list of settings.

Thank you for your patience as we try to roll out this especially difficult deprecation! Please let us know if you have more questions or concerns.

Thanks a lot for the detailed answer, really interesting! Good luck on the fix.