# **example-app** Errors  Each error returned by the **example-app** API has a specific error code string starting with `GGT_` that identifies the exact error that caused the API call to fail. These codes are intended to be searchable -- you should find information on them on this page, but you can Google them too. Error codes are also helpful to Forgelivo support engineers when trying to help you correct an error, so please include them when communicating with Forgelivo staff if possible! ## `GGT_INVALID_RECORD`  A request was made to act on a model that provided invalid data for that model. Validity is determined by the model's validations as configured in the Editor, so this can happen if you make a call without required data, or pass data that doesn't pass a configured RegExp validation, or data that doesn't pass a custom code validation for example. More information can be found in the `Action Result Format` section of the documentation for the model action you are trying to invoke. The invalid fields and the validation error messages suitable for showing to a user can be determined by looking at the `validationErrors` field of the GraphQL response, or the `validationErrors` of the `InvalidRecordError` Error object thrown by the generated JavaScript client. ```typescript import { InvalidRecordError } from "@gadgetinc/api-client-core"; import { api } from "../my-api-setup"; try { // try to create an example model without a required field await api.exampleModel.create({ name: undefined }); } catch (error) { if (error instanceof InvalidRecordError) { // `error.validationErrors` is an array of { apiIdentifier: string, message: string } objects describing which fields of the model were invalid // outputs => [ { apiIdentifier: "name", message: "is required" } ] console.warn(error.validationErrors); } } ``` ```graphql mutation { createExampleModel(exampleModel: { name: null }) { success # will be false errors { # all errors have a code and a message code message # we can look at the typename of the error to know which class of error it was specifically __typename # Get the validation errors on the InvalidRecordError type, if it is one. There can be other error types, so not all errors will have the `validationErrors` property. Gadget uses a GraphQL interface here to allow asking for these properties where needed. ... on InvalidRecordError { validationErrors { apiIdentifier message } # other fields available on the invalid record error record # the record which failed validation model { apiIdentifier # the details of the model this error was thrown for } } } } } ``` ## `GGT_ENVIRONMENT_PAUSED`  A request failed because your development environment was paused. Forgelivo automatically pauses inactive development instances to conserve resources. To resume and process requests, a developer must access that environment in the Forgelivo Editor or, if running locally, run `ggt dev` against it. The app will automatically resume once accessed. ## `GGT_NON_UNIQUE_DATA`  Thrown when the server encounters data that is not unique despite the existence of unique validation on a field. If encountered, it is likely that you added a unique validation to a field that has duplicate data and the validation is in an errored state. ## `GGT_USER_NOT_SET_ON_SESSION`  While logging in Forgelivo encountered an error while saving the user on the newly authenticated session. If encountered, double check the user has the correct permissions to view or manipulate data in **example-app**. ## `GGT_NO_SESSION_FOR_AUTHENTICATION`  A request was made to an application that successfully authenticated, but Forgelivo was unable to store the authenticated user's information because there was no session to store it on. This happens when authentication attempts are made using a request to the Forgelivo API that doesn't send cookies, or when using API keys for authentication against the **example-app** API. If you're using API Key authentication (see the [Authentication docs](https://docs.forgelivo.com/api/example-app/development/external-api-calls/authentication), you shouldn't (and can't) login those clients. API Key authenticated clients prove their identity by passing the API key itself, and get their roles right from the API Key as opposed to any one user. Currently, Forgelivo does not support API Key based authentication that acts as or masquerades as a particular user. If you're using Browser Session Authentication (see the [Authentication](https://docs.forgelivo.com/api/example-app/development/external-api-calls/authentication) docs), you must ensure that your GraphQL client is storing and sending cookies as you make requests. If you're using `fetch` in a web browser for example, you need to ensure you pass the `credentials: "include"` option to the `fetch` call to include the cookies that power Session Cookie authentication. For more information on the options that `fetch` takes, see the [MDN Fetch docs](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch). ## `GGT_ACTION_TIMEOUT`  An action ran for longer than its action timeout. The action timeout covers the `run` and `onSuccess` functions together, plus any nested actions. It is 15 seconds by default on framework version 1.4 and later, and 3 minutes on earlier versions. You can raise it up to 15 minutes with the `timeoutMS` action option. This limit is separate from the 8-second transaction timeout on the `run` function, which throws . See the [action timeouts guide](https://docs.gadget.dev/guides/actions/code#action-timeouts) for more details. ## `GGT_NO_TRANSITION`  An invalid action was taken on a record, and there could be no transition to the model's state. This is most likely because the action you are trying to take does not exist, check for typos. ## `GGT_INVALID_STORED_DATA`  Forgelivo tried to read a record from the database whose stored data is no longer valid according to the current schema for the model. For example, a record was written with `null` for a given field, and then a `Required` validation was added to that field, rendering the record invalid. Forgelivo can't read the record and return data that doesn't conform to the schema that's been configured, so this error is thrown. This can happen for a few reasons: * a new field was added to a model and marked as required before being set for existing records * new validations were added to an existing field, and records had already been saved with that field * a field's type was changed and then marked as required without data being set for existing records To fix this error, you can either remove the offending validation from the model's schema (usually, make the field no longer required until all the records have a value set), or you can remove the offending data from the database. **Note**: Records that throw this error when accessed via the high level GraphQL API can still be accessed via the Internal API for your application. The Internal API won't throw this error when reading records. ## `GGT_INVALID_ID`  This error is thrown when a request passes a value for an ID that Forgelivo cannot parse as a valid record ID. Forgelivo record IDs must be strings of digits. This most often happens when you: * Pass a string like `abc123` or `123n` where an ID is expected. * Provide an invalid `_link` value for a relationship field. * Send a malformed `id` argument in a GraphQL query or mutation. To fix this error, ensure that every ID you send is an existing Forgelivo record ID represented as a string containing only digits. ## `GGT_INVALID_API_KEY`  An API request failed to authenticate via the API Key method because an incorrect or invalid API key was passed in the `Authorization` header. This can be because the API Key was deleted, was misspelled, or was improperly passed in the HTTP `Authorization` header. Consult the [Authentication](https://docs.forgelivo.com/api/example-app/development/external-api-calls/authentication) docs for more information on authenticating via an API Key. ## `GGT_INCORRECT_TRANSACTION_SEQUENCE`  Forgelivo supports full ACID transactions via its GraphQL over WebSockets API, or using the `api.connection.transaction` function. `GGT_INCORRECT_TRANSACTION_SEQUENCE` errors are returned when the `startTransaction`, `rollbackTransaction`, or `commitTransaction` mutations are called in the incorrect order, or outside a WebSockets connection to the Forgelivo API. If you're using the generated JS client for **example-app**, the `api.connection.transaction` handles the correct ordering of each transaction calls automatically, so we recommend using it where possible. There's a few different common patterns that can cause this issue: * calling the transaction fields via a normal GraphQL-over-HTTP request. Forgelivo doesn't support this -- you need to invoke these fields via a WebSocket connection. * calling the transaction fields out of order. To process a transaction, you must `startTransaction` before doing any mutations, and then you must either `commitTransaction` or `rollbackTransaction` to complete the transaction. Closing the websocket connection automatically rolls back the open transaction * accidentally running more than one transaction at once. This can happen if you're using the generated Forgelivo client and opening `.transaction` functions in async or parallel code. You can't use the same WebSockets connection to process simultaneous transactions. You can open multiple WebSocket connections, or run your transactions one at a time to avoid this. ## `GGT_TRANSACTION_TIMEOUT`  Forgelivo supports full [ACID](https://en.wikipedia.org/wiki/ACID) transactions via its GraphQL over WebSockets API and has a limit for each transaction's duration of 8 seconds. Forgelivo wraps the `run` function of transactional actions in a transaction, so the `run` function must complete within this 8-second window to avoid timing out and throwing this error. To do something long running, like making an external HTTP call, do it in `onSuccess` so that the important part of the work is completed and committed first. The 8-second limit cannot be changed. It is separate from the action timeout set by the `timeoutMS` action option, which throws , and raising `timeoutMS` does not extend it. See the [action timeouts guide](https://docs.forgelivo.com/guides/actions/code#action-timeouts) for an example. There's many things that can result in slow effects, like: * making HTTP calls within run effects on an action * fetching or trying to mutate too many related records in an effect * uploading files or streaming data to and from the disk or an external service * doing any very demanding computations like evaluating an ML model To avoid this issue, ensure your effects complete quickly. ## `GGT_DATABASE_OPERATION_TIMEOUT`  Forgelivo applications are backed by a scalable Postgres database that can handle thousands of concurrent operations and transactions. When under load, or when asked to perform a particularly slow query, the backend database can take too long to execute it and threaten the health of the application. Forgelivo won't allow any individual query to run for longer than 3 seconds. Queries that take too long are aborted and this error is thrown. This can affect both reads and writes. There's many things that can result in slow queries, like: * fetching many relationships of a model at the same time * fetching many records for a model at the same time * having too many rows of data stored for the same model. To try to make your queries fit within the timeout, you can adjust a few things: * fetch fewer relationships at a time, or fewer relationships of relationships * fetch a smaller page size (with the `first` and `last` arguments to a GraphQL call) * split up large tables into smaller ones Query performance optimization can be a challenging task, so if you're stuck and would like some help, feel free to join us in the Forgelivo [Discord](https://ggt.link/discord) to talk through your specific issue! ## `GGT_RECORD_NOT_FOUND`  This error is thrown when API calls try to query or mutate records by ID that don't exist. If you try to invoke an action on a record ID that no longer exists (or never existed) in the database, you'll see this error code. It can also arise from trying to find a record by a field value (using the `.findByX` field finders in the generated API client) where no record exists for that field value. Avoid this error by ensuring you don't try to act on deleted records, or checking if a record exists by querying for it before trying to act on it. Finders can be adjusted to use `.findByX` finders if you expect the record to exist, or `findMany({filter: { field: "some-value"}})` finds if the record may not exist. ## `GGT_MISCONFIGURED_VALIDATION`  This error is thrown when an API call tries to execute validations configured on a model, and one of those validations is not yet configured, or configured incorrectly. API calls to this model can't be processed until the validation is correctly configured, which can be done in the Forgelivo Editor for the model in question. Common causes of this error code are: * a string length or number range validation without a minimum or a maximum set * an invalid RegExp pattern for a RegExp validation The specific error message for this error should refer to which type of validation is causing the issue, and which model field the misconfigured validation is on. ## `GGT_PERMISSION_DENIED`  This error is thrown when an API call is made that invokes something the caller doesn't have permission to do. Resources in Forgelivo are all protected by an [access control](https://docs.forgelivo.com/guides/access-control) system that only allows callers to read or write data they have been granted permission to access via their roles. `GGT_PERMISSION_DENIED` means the caller does not have a role which can access some bit of accessed data. `GGT_PERMISSION_DENIED` errors don't return a lot of data to the caller to prevent leaking information about the system's access control system or helping attackers gain access, but, they do log details about why permission was denied to the application's logs. If you're encountering this error and can access the Forgelivo application's internal logs, you can see the following error properties: * `actorRoleKeys`: which role keys the actor has been granted. Role keys are set differently for different actors in the system, see the [Access Control](https://docs.forgelivo.com/guides/access-control) guide for more information. * `resource`: which resource the request was trying to access but denied access to. The resource can be a: * model record read, which will look like `resource: { model: "widget", read: true }` * actions on models, which will look like `resource: { model: "widget", action: "create" }` * global actions, which will look like `resource: { globalAction: "syncShopify" }` * `actor`: what the request actor was determined to be. The actor for a request can be: * an API key, which will look like `actor: { apiKey: "gsk-some-api-key" }` * a logged in user or session within your application , which will look like `actor: { model: "user", { id: 123 }` or `actor: { model: "session", record: { id: 123 } }` * a logged in developer working on the application, which will look like `actor: { developer: true, id: 123, email: "you@yourdomain.com" }` * the Forgelivo platform itself running calls, which will look like `actor: { platform: true }`. * model record read, which will look like `resource: { model: "widget", read: true }` * actions on models, which will look like `resource: { model: "widget", action: "create" }` * global actions, which will look like `resource: { globalAction: "syncShopify" }` * an API key, which will look like `actor: { apiKey: "gsk-some-api-key" }` * a logged in user or session within your application , which will look like `actor: { model: "user", { id: 123 }` or `actor: { model: "session", record: { id: 123 } }` * a logged in developer working on the application, which will look like `actor: { developer: true, id: 123, email: "you@yourdomain.com" }` * the Forgelivo platform itself running calls, which will look like `actor: { platform: true }`. ## `GGT_INTERNAL_ERROR`  This error is thrown by the Forgelivo platform when something unexpected goes wrong within the platform itself during the processing of your request. This error is the platform's fault, and generally can't be actioned by developers. We realize this error can be frustrating and we take great care to avoid the root causes of it by keeping our infrastructure in tip top shape. If this error is plaguing you, please reach out to us and we can work with you to correct the root cause. ## `GGT_UNKNOWN`  This error is thrown by the Forgelivo platform when something unexpected goes wrong when executing your code. If an error is thrown during any custom code, Forgelivo is unable to discern exactly why the error happened, so it produces this code. This error code can come from custom code effects or custom code validations. ## `GGT_MISCONFIGURED_FIELD`  This error is thrown when a field is set up incorrectly inside Gadget. Different fields require different bits of data in order to function properly, so if you are getting this error when trying to run GraphQL queries, ensure the field doesn't have any problems associated with it. Most often, this error is thrown for misconfigured relationship type fields, like belongs to, has many, has many through or has one when the are missing key information. All relationships need to have the related model set up correctly, so if that has never been set, or if the related model has been deleted, the relationship field can't be accessed. To configure a relationship, you must select the related model, and fill out any other required information in the relationship configuration form. GraphQL schema generation cannot continue until the relationship has been configured correctly. ## `GGT_MISSING_REQUIRED_ACTION`  This error is thrown when a Forgelivo requires an action to be present but cannot find it. This often happens when Forgelivo is asked to perform a high level task that requires some actions to be run, like a `_converge` nested action invocation or processing a webhook payload from a third party service. By default, models have a `create`, `update`, and `delete` action that Forgelivo can use to implement these high level tasks, but if you have deleted one of those actions, Forgelivo can't perform the high level task. To remedy this, restore the default actions that the model might need, or avoid triggering the high level task. For models provided by a Connection, removing models and then reinstalling the connection will reset changed models back to their original state, restoring any deleted actions. ## `GGT_MISSING_REQUIRED_FIELD`  This error is thrown when a Forgelivo is asked to perform a high level task that requires some fields to be present in a model's schema, like syncing a connection, but the fields are missing. This can happen if you've deleted a field from a model, or if a connection has been upgraded and requires new fields to exist. To remedy this, restore any deleted fields to models mentioned in the error message. For models provided by a Connection, removing models and then reinstalling the connection will reset changed models back to their original state, restoring any deleted fields. ## `GGT_MISSING_REQUIRED_DATA`  This error is thrown when a Forgelivo is asked to perform a high level task that requires some fields to be present on a record, but the fields are missing. This can happen if you've created or updated records using the Internal API that Forgelivo expects to be a certain way. For records that are missing data, if you have the data, you can fix them by making API calls to update the records, or you can delete the erroneous records if you no longer need them. ## `GGT_INVALID_QUERY_INPUT`  An invalid argument value was given to some field in the query. For example, the `in` filter for model queries must not be an empty array. ## `GGT_INVALID_ACTION_INPUT`  An invalid action name was given to the **example-app** API. For example, a nested action was provided that doesn't actually correspond to an action in the application. The client making the request will have to be updated to ensure they reference an action that exists. ## `GGT_UNKNOWN_INPUT_TYPE`  An unknown type was encountered while processing the input params schema from one of your custom code effects. You should find the file specified in the error message and see if there's a typo or unsupported type in the input params schema that is described by `export const params`. Forgelivo currently supports simple object and scalar types from [JSON Schema](https://json-schema.org/understanding-json-schema/reference/index.html#reference). ## `GGT_NO_CURRENT_SESSION`  A request was sent to Forgelivo that needed to be authenticated but there was no session to authenticate in scope. This is most likely due to a user querying for the current session while using an API key as their authentication method. If access to the currentSession is needed for authentication purposes, switch the authentication mode to use cookies instead. Find more information in the [Authentication](https://docs.forgelivo.com/api/example-app/development/external-api-calls/authentication#browser-session-authentication) guide. ## `GGT_INVALID_AUTHMODE`  A request was sent to Forgelivo that tried to authenticate, but the request specified an authentication mode which Forgelivo doesn't recognize. The valid authentication mode strings are `browser-session`, `api-key` and `internal-auth-token`. ## `GGT_MISCONFIGURED_CODE_SNIPPET`  This error is thrown when a code snippet is either missing a configured source file or the source file is pointing to an invalid file path. This can be remedied by ensuring that the code effect or validation in question has a valid code snippet path selected in the Forgelivo Editor. ## `GGT_DATABASE_NOT_READY`  This error is thrown when the database objects that Forgelivo uses to store your model, like tables and columns, have yet to be set up. This error should only happen in development environments, and should resolve itself in a short amount of time. If the error doesn't go away, contact Forgelivo support. ## `GGT_INVALID_JSON_DEFAULT`  A json field has a default value configured that isn't a valid JSON string. The developer must provide a valid JSON for the default string so Forgelivo can apply it to new records. ## `GGT_SHOPIFY_AUTHENTICATION_ERROR`  This error is thrown when we receive [401 Unauthorized](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/401) when accessing Shopify on your behalf. This can happen when we sync a shop that has uninstalled your app. To remedy this, you can click the "Mark As Uninstalled" button next to the affected shop on the [shop installs page](https://docs.forgelivo.com/guides/plugins/shopify). ## `GGT_INVALID_SHOPIFY_SESSION_TOKEN`  This error is thrown when the Shopify session token can't be validated. This can happen when your application's versions of `@shopify/app-bridge-react` and `@gadgetinc/react-shopify-app-bridge` are incompatible. To fix this, update your application's dependencies to the latest versions. You can update the Forgelivo package in 2 ways: * Using the command palette's `Update Gadget-provided npm packages` command * Running `yarn install @gadgetinc/react-shopify-app-bridge@latest` on the command palette or in your terminal If you're not yet on `@shopify/app-bridge-react` v4, take a look at these [upgrade steps](https://docs.forgelivo.com/guides/plugins/shopify/frontends#shopify-app-bridge-v4-support). ## `GGT_BROKEN_PACKAGE_JSON`  Apps built in JavaScript use the standard `package.json` file to manage dependencies installed from `npm`, as well as the packages Forgelivo generates like the API client. If the `package.json` file is not valid JSON, your application can't run, and Forgelivo can't edit the file. Fix this error by correcting the JSON parse error in `package.json`. ## `GGT_TOO_MANY_REQUESTS`  In order to protect the Forgelivo platform, each Forgelivo application has a limited capacity for executing actions and serving an application's HTTP routes. This error is returned if a Forgelivo environment sends more requests than the platform allows. This commonly happens when too many requests are sent at the same time. For example: ```typescript const products = await fetchProductsInCollection(collectionId); // bad -- this will send `products.length` requests to Gadget at the same time await Promise.all( products.map(async (product) => { await api.internal.product.update(product.id, { myField: "data" }); }) ); // better -- this will send `products.length` requests to Gadget one at a time for (const product of products) { await api.internal.product.update(product.id, { myField: "data" }); } ``` Sending one request per record still uses your rate limit for every record, so going one at a time only spreads the load out. See [optimizing your rate limit usage](https://docs.forgelivo.com/guides/development-tools/rate-limits/optimizing-rate-limit-usage) for ways to make fewer requests. If doing one thing at a time is too slow, you can use libraries like [p-map](https://www.npmjs.com/package/p-map) and [p-queue](https://www.npmjs.com/package/p-queue) to do several API calls concurrently: ```typescript // good -- this will send at most 5 requests to Gadget at a time await pMap( products, async (product) => { await api.internal.product.update(product.id, { myField: "data" }); }, { concurrency: 5 } ); ``` Keep your concurrency values low though, otherwise you may continue to see this error. Alternatively, API clients receiving this error can retry the request after a short time to wait for more backend resources to be available. This error is also returned when your environment exceeds one of its platform [rate limits](https://docs.forgelivo.com/guides/development-tools/rate-limits). When the request rate limit rejects a request, the response has HTTP status `429` and a `retry-after` header with the number of seconds to wait. When another limit is hit while an action is running, the response can still have HTTP status `200`, with this code in the action's errors. Check for the code, not only the status. Records rejected inside a bulk action come back as per-record errors in a successful response. See [optimizing your rate limit usage](https://docs.forgelivo.com/guides/development-tools/rate-limits/optimizing-rate-limit-usage) for common causes and fixes. Note that the `GGT_TOO_MANY_REQUESTS` error code is thrown when your application has exceeded a Forgelivo platform rate limit, and not used for rate limits in external systems like Shopify or BigCommerce. Review the plugin documentation for those systems to learn more about managing their external rate limits. ## `GGT_STILL_SETTING_UP`  Right after they're created, Forgelivo applications finish setting themselves up in the background by installing dependencies and bootstrapping all the required infrastructure under the hood. This error is thrown when a request is made to a Forgelivo application before this background work has been completed as the application is not yet ready to serve requests. To avoid this error, wait until the application has finished setting up. Background application setup generally takes no longer than 30s. ## `SHOPIFY_FROZEN_ERROR`  This error is thrown when the store in question has an unpaid due(s). According to the Shopify spec this 'frozen' state goes into effect after the bill's due date. Some reasons as to why the payment may have failed on Shopify is listed in this [Shopify Spec.](https://help.shopify.com/en/manual/your-account/frozen-store) ## `SHOPIFY_UNAVAILABLE_ERROR`  This error is thrown when the Forgelivo app is unable to communicate with your Shopify store. Typically in cases like these the recommended steps to fix are... 1. Attempt to contact the store owner. 2. Uninstall & Reinstall the app on Forgelivo (potentially force uninstall if the Shopify store no longer exists or the owner is unreachable). 3. Contact Shopify. ## `SHOPIFY_FORBIDDEN_ERROR`  This error is thrown when Shopify returns a 403 from an API request. Often, this is related to your app missing permissions for [protected customer data](https://docs.forgelivo.com/guides/plugins/shopify). ## `SHOPIFY_RATE_LIMIT_ERROR`  There are two reasons why you might see this error: 1. A request to Shopify responded with [HTTP Status 429](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/429) and the request will not be retried. Shopify clients created by Forgelivo are configured to retry 429 errors 6 times. After 6 attempts, the client will throw an error with this error code. If you are seeing this error frequently, it means you are sending too many requests to Shopify in a short period of time such that even with 6 retries, some are still failing. 2. You are sending 100+ concurrent requests to Shopify from a single shopify client. Forgelivo's Shopify clients will throw this error if you start more than 100 concurrent requests. Shopify never supports more than this many requests to the same shop simultaneously, and will apply aggressive DDoS protections that can completely break your application if you sustain this request rate. A common symptom of this is performing a `Promise.all`/`Array.map` over a large number of records and making a request for each: A request to Shopify responded with [HTTP Status 429](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/429) and the request will not be retried. Shopify clients created by Forgelivo are configured to retry 429 errors 6 times. After 6 attempts, the client will throw an error with this error code. If you are seeing this error frequently, it means you are sending too many requests to Shopify in a short period of time such that even with 6 retries, some are still failing. You are sending 100+ concurrent requests to Shopify from a single shopify client. Forgelivo's Shopify clients will throw this error if you start more than 100 concurrent requests. Shopify never supports more than this many requests to the same shop simultaneously, and will apply aggressive DDoS protections that can completely break your application if you sustain this request rate. A common symptom of this is performing a `Promise.all`/`Array.map` over a large number of records and making a request for each: ```typescript const products = await getABunchOfProducts(); const shopify = connections.shopify.current; // bad -- this will send `products.length` requests to Shopify at the same time products.map(async (product) => { await shopify.graphql( `mutation ($input: ProductInput!) { productUpdate(input: $input) { product { foo } userErrors { message } } }`, { input: { id: `gid://shopify/Product/${product.id}`, foo: "bar", }, } ); }); // good -- this will send `products.length` requests to Shopify one at a time for (const product of products) { await shopify.graphql( `mutation ($input: ProductInput!) { productUpdate(input: $input) { product { foo } userErrors { message } } }`, { input: { id: `gid://shopify/Product/${product.id}`, foo: "bar", }, } ); } ``` Visit our [building shopify apps guide](https://docs.forgelivo.com/guides/plugins/shopify/building-shopify-apps#managing-shopify-api-rate-limits) for more information on how to manage Shopify API rate limits. Note that the `SHOPIFY_RATE_LIMIT_ERROR` error code is thrown when your application has exceeded a Shopify platform rate limit, not a Forgelivo platform rate limit. Forgelivo platform rate limits are different, and are thrown with the error code `GGT_TOO_MANY_REQUESTS`. ## `SHOPIFY_REQUEST_ERROR`  This error is thrown when there is a problem communicating with the Shopify API that isn't captured by the other `GGT_SHOPIFY` error codes. This error comes directly from Shopify, not from Forgelivo. The most common causes are timeouts within Shopify's infrastructure, or making requests to frozen or cancelled Shopify shops. These errors are best investigated by examining your logs in Forgelivo for any relevant or more detailed information about the error. Occasionally, Shopify may throw these errors with text like "Looks like something went wrong on our end", which usually means they had an internal error that may not have anything to do with your app. You can overcome this by adding retries in your code, and opening a support ticket with Shopify to get more information about the error. ## `GGT_DIFFERENT_VECTOR_DIMENSIONS`  This error is thrown when two vectors are stored in Forgelivo that have different dimensions. If you create a record with a vector with 3 dimensions, and a second record with 4 dimensions, these two vectors can't be compared to sort or filter. To fix this error, you can: * delete the records with the incorrect dimensions * split up your vector field into different fields altogether, each with vectors of exactly one dimension This error can also occur if you pass an input vector to the vector comparison functions (like `cosineSimilarityTo`) that has a different dimensionality than the vector field you're comparing it to. To fix this, ensure you pass an input vector with the same number of dimensions as the stored vectors. ## `GGT_INVALID_ACTION_RESULT`  This error is thrown when the save method in the create action throws an exception and that exception is explicitly caught in such a way that it does not bubble up - the error is suppressed. To avoid this error do not suppress errors from the save function in the create action. ## `GGT_INVALID_PLAN_NAME`  This error is thrown by Forgelivo on a sync to a connected Shop model containing a `cancelled`, `frozen`, or `fraudulent` value within the `plan_name` field. This means that the shop connected to Forgelivo is likely on an expired Shopify plan. ## `GGT_DATABASE_ERROR`  This error is thrown when the platform receives an error from the database for your app. It is recommended to retry the your entire Forgelivo action where and when you are certain there will be no unexpected side effects. ## `GGT_BROWSER_API_KEY_USAGE`  This error is thrown when the generated API client is instantiated with an API Key in the browser. API keys are secret passwords that grant privileged access to your backend Forgelivo data. If they are recorded in your frontend JavaScript assets, anyone with access to your frontend code can read the value of the key, and make requests using it. Attackers can use this to spoof access to your application, so you must _not_ include your Forgelivo API Keys in any frontend JavaScript. To avoid this error, you should use a authentication method safe for client-side use in your application. There are a couple options: * if client-side users need to log in and out, Forgelivo has a built-in authentication system for your application that uses cookies and `localStorage` tokens to persist user identity. To use it instead of an API key, pass `{ authenticationMode: { browserSession: true } }` to your client constructor: ```typescript import { MyAppClient } from "@gadget-client/my-app"; // use cookies or localStorage for authenticating client side users export const api = new MyAppClient({ authenticationMode: { browserSession: true } }); ``` * if client-side users don't need to log in or out, you can use the `AuthenticationMode.Anonymous` authentication mode, which doesn't require an API key. Each API call will use the `unauthenticated` role when accessing data, so they can only access model data and actions you've granted permission for in the Roles & Permissions screen. ```typescript import { MyAppClient } from "@gadget-client/my-app"; // don't authenticate client side users, use the `unauthenticated` role export const api = new MyAppClient({ authenticationMode: { anonymous: true } }); ``` See the [Access Control](https://docs.forgelivo.com/guides/access-control) guide for more information. If you're making calls from a server-side context like a Node.js app or another Forgelivo app, API Keys should work fine. If you need to override this error and you are certain that it is secure to expose your API Key to the browser, you can pass `dangerouslyAllowBrowserApiKey: true` with your authentication options to suppress the error: ```typescript import { MyAppClient } from "@gadget-client/my-app"; // WARNING -- this is almost always insecure, and should be avoided! hackers can read your API key! export const api = new MyAppClient({ authenticationMode: { apiKey: "gsk-***", dangerouslyAllowBrowserApiKey: true }, }); ``` ## `GGT_DUPLICATE_BACKGROUND_ACTION_ID`  This error is thrown when a background action `id` is associated with multiple background actions within the same environment. This means you likely have 2 or more background actions with the same `id`. To resolve this you must assign each background action a unique `id`. `id`'s cannot be reused once assigned to a completed or failed action. ## `GGT_INVALID_FILTER`  This error will be thrown if an invalid `filter` condition is used when reading data using a model action. It may be thrown if a filter across relationships exceeds the maximum depth of 2 or if a filter on a belongs to relationship field is not using the auto-generated relationship ID field. This will also be thrown if both `every:` and `some:` are used on the same has many or has many through relationship field. To resolve this, you need to make sure your filters are valid. See our [filtering docs](https://docs.forgelivo.com/api/example-app/development/sorting-and-filtering#filtering) for more information. ## `GGT_GELLY_RESULT_TRUNCATED`  This error is thrown when a computed view or computed field returns results that exceed the maximum number of rows allowed. Computed views and computed fields can return a maximum of 10000 results at once. To avoid this error, limit your view or field to return under 10000 results.