Migrating your app to framework v1.4.0 

Gadget framework version 1.4.0 has some breaking changes that need to be tested before deploying your apps to production.

Node version upgraded to version 22.15.0 

Gadget apps using framework version 1.4.0 will run nodejs version 22.15.0. This is a major version upgrade, and will require some changes to your app.

See more details about Node v22 in the Node.js 22 release announcement and changelog.

DateTime fields are now represented as Date objects 

The representation of date / time fields in model actions has changed from strings to native JavaScript Date objects.

For example, if your model post has a publishedAt field, and you were handling it as a string in your actions:

Example of DateTime handling in framework versions <=1.3
JavaScript
export const run = async ({ params, record, logger, api, connections }) => { // record.publishedAt and params.post.publishedAt are strings const currentPublishedAt = record.publishedAt && new Date(record.publishedAt); const newPublishedAt = params.post?.publishedAt && new Date(params.post.publishedAt); if (currentPublishedAt && newPublishedAt && newPublishedAt > currentPublishedAt) { // do something } };
export const run = async ({ params, record, logger, api, connections }) => { // record.publishedAt and params.post.publishedAt are strings const currentPublishedAt = record.publishedAt && new Date(record.publishedAt); const newPublishedAt = params.post?.publishedAt && new Date(params.post.publishedAt); if (currentPublishedAt && newPublishedAt && newPublishedAt > currentPublishedAt) { // do something } };

After upgrading to v1.4.0, you'll need to update your code to work with Date objects directly:

Example of DateTime handling in framework v1.4
JavaScript
export const run = async ({ params, record, logger, api, connections }) => { // record.publishedAt and params.post.publishedAt are Date objects const currentPublishedAt = record.publishedAt; const newPublishedAt = params.post?.publishedAt; if (currentPublishedAt && newPublishedAt && newPublishedAt > currentPublishedAt) { // do something } };
export const run = async ({ params, record, logger, api, connections }) => { // record.publishedAt and params.post.publishedAt are Date objects const currentPublishedAt = record.publishedAt; const newPublishedAt = params.post?.publishedAt; if (currentPublishedAt && newPublishedAt && newPublishedAt > currentPublishedAt) { // do something } };

All date / time fields in model actions will now be native JavaScript Date objects, eliminating the need for manual Date object creation.

Default action timeout reduced to 15 seconds 

The default timeout for model actions has been reduced from 3 minutes to 15 seconds. This affects any action that doesn't have an explicit timeout set.

Actions will now throw errors if the combined duration of the run and onSuccess functions exceeds 15 seconds. Actions that have explicit timeouts set will not be affected.

To set an explicit timeout for a long running action, you can use the timeoutMS action option:

Example of setting an explicit action timeout
JavaScript
export const run = async ({ params, record, logger, api, connections }) => { // some action logic }; export const options = { timeoutMS: 60000, // set a 1 minute timeout };
export const run = async ({ params, record, logger, api, connections }) => { // some action logic }; export const options = { timeoutMS: 60000, // set a 1 minute timeout };

Review your actions and set appropriate timeouts for any that may need more than 15 seconds to complete.

If you have issues after upgrading to v1.4.0 reach out on our Discord.

Multiple roles independently grant permissions 

Previously, Gadget's access control system required all the roles of a request actor to be able to perform an operation to allow it. For example, if a user had both the reader and writer roles, and tried to run an action that only the writer role could perform, the request would with a GGT_PERMISSION_DENIED error, as not all the roles could perform the action.

Now, Gadget's access control system will allow a request actor to perform an operation if any of the roles they have been granted are able to perform it. If a user has both the reader and writer roles, and tries to run an action that only the writer role could perform, the request will succeed, as the user has at least one role that can perform the action.

Permission enforcement behavior for request actors that have only one role is unchanged.

Review your role permissions to ensure users holding multiple roles can only perform the reads and actions required.

Was this page helpful?