Errors

This section contains formation and guidance related to Errors thrown by ElectroDB.

ElectroError

ElectroDB wraps errors with an ElectroError class exception. This class extends error and adds additional metadata/properties for additional context.

export class ElectroError<E extends Error = Error> extends Error {
  readonly name: "ElectroError";
  readonly code: number;
  readonly date: number;
  readonly cause: E | undefined;
  readonly isElectroError: boolean;
  ref: {
    readonly code: number;
    readonly section: string;
    readonly name: string;
    readonly sym: unique symbol;
  };
}

export interface ElectroValidationErrorFieldReference<T extends Error = Error> {
  /**
   * The json path to the attribute that had a validation error
   */
  readonly field: string;

  /**
   * A description of the validation error for that attribute
   */
  readonly reason: string;

  /**
   * Index of the value passed (present only in List attribute validation errors)
   */
  readonly index: number | undefined;

  /**
   * The error thrown from the attribute's validate callback (if applicable)
   */
  readonly cause: T | undefined;
}

export class ElectroValidationError<
  E extends Error = Error,
> extends ElectroError<E> {
  readonly fields: ReadonlyArray<ElectroValidationErrorFieldReference<E>>;
}

In the event of an error thrown by the AWS Client (e.g. ConditionalCheckFailedException), the original error will be wrapped with an ElectroError and the original error will be accessible via the cause property. Pass the error type expected for your given client as the first generic argument to ElectroError to strongly type the returned error beyond the base Error class.

Error Classifications

Errors are coded based on the type of error that has occurred.

Error CodeDescription
1000sConfiguration Errors
2000sInvalid Query Errors
3000sUser Defined Validation
4000sDynamoDB Errors
5000sUnexpected Errors

Configuration Errors

No Client Defined On Model

Code: 1001

Why this occurred: If a DynamoDB DocClient is not passed to the constructor of an Entity or Service (client), ElectroDB will be unable to query DynamoDB. This error will only appear when a query(using go()) is made because ElectroDB is still useful without a DocClient through the use of it’s params() method.

What to do about it: For an Entity be sure to pass the DocClient as the second param to the constructor:

new Entity(schema, { client });

For a Service, the client is passed the same way, as the second param to the constructor:

new Service("", { client });

Invalid Identifier

Code: 1002

Why this occurred: You tried to modify the entity identifier on an Entity.

What to do about it: Make sure you have spelled the identifier correctly or that you actually passed a replacement.

Invalid Key Composite Attribute Template

Code: 1003

Why this occurred: You are trying to use the custom Key Composite Attribute Template, and the format you passed is invalid.

What to do about it: Checkout the section on [Composite Attribute Templates](/en/modeling/indexes#composite attribute-templates) and verify your template conforms to the rules detailed there.

Duplicate Indexes

Code: 1004

Why this occurred: Your model contains duplicate indexes. This could be because you accidentally included an index twice or even forgot to add an index name on a secondary index, which would be interpreted as “duplicate” to the Table’s Primary index.

What to do about it: Double-check the index names on your model for duplicate indexes. The error should specify which index has been duplicated. It is also possible that you have forgotten to include an index name. Each table must have at least one Table Index (which does not include an index property in ElectroDB), but all Secondary and Local indexes must include an index property with the name of that index as defined on the table.

{
  indexes: {
    index1: {
      index: "idx1", // <-- duplicate "idx1"
      pk: {},
      sk: {}
    },
    index2: {
      index: "idx1", // <-- duplicate "idx1"
      pk: {},
      sk: {}
    }
  }
}

Collection Without An SK

Code: 1005

Why this occurred: You have added a collection to an index that does not have an SK. Because Collections are used to help query across entities via the Sort Key, not having a Sort Key on an index defeats the purpose of a Collection.

What to do about it: If your index does have a Sort Key, but you are unsure of how to inform electro without setting composite attributes to the SK, add the SK object to the index and use an empty array for Composite Attributes:

// ElectroDB interprets as index *not having* an SK.
{
  indexes: {
    myIndex: {
      pk: {
        field: "pk",
        composite: ["id"]
      }
    }
  }
}
// ElectroDB interprets as index *having* SK, but this model does not attach any composite attributes to it.
{
  indexes: {
    myIndex: {
      pk: {
        field: "pk",
        composite: ["id"]
      },
      sk: {
        field: "sk",
        composite: []
      }
    }
  }
}

Duplicate Collections

Code: 1006

Why this occurred: You have assigned the same collection name to multiple indexes. This is not allowed because collection names must be unique.

What to do about it: Determine a new naming scheme

Missing Primary Index

Code: 1007

Why this occurred: DynamoDB requires the definition of at least one Primary Index on the table. In Electro this is defined as an Index without an index property. Each model needs at least one, and the composite attributes used for this index must ensure each composite represents a unique record.

What to do about it: Identify the index you’re using as the Primary Index and ensure it does not have an index property on its definition.

// ElectroDB interprets as the Primary Index because it lacks an `index` property.
{
  indexes: {
    myIndex: {
      pk: {
        field: "pk",
        composite: ["org"]
      },
      sk: {
        field: "sk",
        composite: ["id"]
      }
    }
  }
}
// ElectroDB interprets as a Global Secondary Index because it has an `index` property.
{
  indexes: {
    myIndex: {
      index: "gsi1"
      pk: {
        field: "gsi1pk",
        composite: ["org"]
      },
      sk: {
        field: "gsi1sk",
        composite: ["id"]
      }
    }
  }
}

Invalid Attribute Definition

Code: 1008

Why this occurred: Some attribute on your model has an invalid configuration.

What to do about it: Use the error to identify which column needs to examined, double-check the properties on that attribute. Checkout the section on Attributes for more information on how they are structured.

Invalid Model

Code: 1009

Why this occurred: Some properties on your model are missing or invalid.

What to do about it: Checkout the section on Schemas to verify your model against what is expected.

Invalid Options

Code: 1010

Why this occurred: Some properties on your options object are missing or invalid.

What to do about it: Checkout the section on Model/Service Options to verify your model against what is expected.

Duplicate Index Fields

Code: 1014

Why this occurred: An Index in your model references the same field twice across indexes. The field property in the definition of an index is a mapping to the name of the field assigned to the PK or SK of an index.

What to do about it: This is likely a typo, if not double-check the names of the fields you assigned to be the PK and SK of your index, these field names must be unique.

Duplicate Index Composite Attributes

Code: 1015

Why this occurred: Within one index you tried to use the same composite attribute in both the PK and SK, and that SK contained more than one composite attribute. With DynamoDB, there is a lot of literature that advocate using the same value as both the PK and SK when a Sort Key exists on a table — this usually is done because some value is required in that column but for that entity it is not necessary. This constraint is critical for ElectroDB to reliably generate/format sort key values. If this is your situation remember that ElectroDB does put a value in the SortKey even when you model does not define a composite attribute, checkout this section for more information.

What to do about it: Determine how you can change your access pattern to not duplicate the composite attribute. Remember that an empty array for an SK is valid.

Incompatible Key Composite Attribute Template

Code: 1017

Why this occurred: You are trying to use the custom Key Composite Attribute Template, and a Composite Attribute Array on your model, and they do not contain identical composite attributes.

What to do about it: Checkout the section on Composite Attribute Templates and verify your template conforms to the rules detailed there. Both properties must contain the same attributes and be provided in the same order.

Invalid Index With Attribute Name

Code: 1018

Why this occurred: ElectroDB’s design revolves around best practices related to modeling in single table design. This includes giving indexed fields generic names. If the PK and SK fields on your table indexes also match the names of attributes on your Entity you will need to make special considerations to make sure ElectroDB can accurately map your data.

What to do about it: Checkout the section Using ElectroDB with existing data to learn more about considerations to make when using attributes as index fields.

Invalid Collection on Index With Attribute Field Names

Code: 1019

Why this occurred: Collections allow for unique access patterns to be modeled between entities. It does this by appending prefixes to your key composites. If an Entity leverages an attribute field as an index key, ElectroDB will be unable to prefix your value because that would result in modifying the value itself.

What to do about it: Checkout the section Collections to learn more about collections, as well as the section Using ElectroDB with existing data to learn more about considerations to make when using attributes as index fields.

Invalid Query Errors

Missing Composite Attributes

Code: 2002

Why this occurred: The current request is missing some composite attributes to complete the query based on the model definition. Composite Attributes are used to create the Partition and Sort keys. In DynamoDB Partition keys cannot be partially included, and Sort Keys can be partially include they must be at least passed in the order they are defined on the model.

What to do about it: The error should describe the missing composite attributes, ensure those composite attributes are included in the query or update the model to reflect the needs of the access pattern.

Missing Table

Code: 2003

Why this occurred: You never specified a Table for DynamoDB to use.

What to do about it: Tables can be defined on the Service Options object when you create an Entity or Service, or if that is not known at the time of creation, it can be supplied as an Execution Option and supplied on each query individually. If are supplied to both, in that case the Query Option will override the Service Option.

Invalid Concurrency Option

Code: 2004

Why this occurred: When performing a bulk operation (Batch Get, Batch Delete Records, Batch Put Records) you can pass an Execution Option called concurrent, which impacts how many batch requests can occur at the same time. Your value should pass the test of both, !isNaN(parseInt(value)) and parseInt(value) > 0.

*What to do about it: * Expect this error only if you’re providing a concurrency option. Double-check the value you are providing is the value you expect to be passing, and that the value passes the tests listed above.

Invalid Pages Option

Code: 2005

Why this occurred: When performing a Query you can pass an Execution Option called pages, which impacts how many DynamoDB pages a query should iterate through. Your value should pass the test of both, !isNaN(parseInt(value)) and parseInt(value) > 0.

What to do about it: Expect this error only if you’re providing a pages option. Double-check the value you are providing is the value you expect to be passing, and that the value passes the tests listed above.

Invalid Limit Option

Code: 2006

Why this occurred: When performing a Query you can pass an Execution Option called limit, which impacts how many DynamoDB items a query should return. Your value should pass the test of both, !isNaN(parseInt(value)) and parseInt(value) > 0.

What to do about it: Expect this error only if you’re providing a limit option. Double-check the value you are providing is the value you expect to be passing, and that the value passes the tests listed above.

Invalid Index Composite Attributes Provided

Code: 2012

Why this occurred: This error occurs on the mutation operations put, create, upsert, update, and patch when using the condition callback in your Entity’s schema. When a conditional index is defined, all member attributes of the index must be provided if a mutation operation affects one of the attributes. This is to ensure that the index is kept in sync with the item’s attributes. More information and the discussion around the reasoning behind this change can be found here.

What to do about it: If you need to modify a single composite attribute on a multi-composite attribute GSI, you will need to provide new values for all member composite attributes. In the case of update/patch, if you are unable to update all member attributes (e.g. because some are readOnly) you can also use the composite method on update and patch.

User Defined Validation

Invalid Attribute

Code: 3001

Why this occurred: The value received for a validation either failed type expectations (e.g. a “number” instead of a “string”), or the user provided “validate” callback on an attribute rejected a value.

What to do about it: Examine the error itself for more precise detail on why the failure occurred. The error object itself should have a property called “fields” which contains an array of every attribute that failed validation, and a reason for each. If the failure originated from a “validate” callback, the originally thrown error will be accessible via the cause property the corresponding element within the fields array.1

Below is the type definition for an ElectroValidationError:

ElectroValidationError<T extends Error = Error> extends ElectroError {
    readonly name: "ElectroValidationError"
    readonly code: number;
    readonly date: number;
    readonly isElectroError: boolean;
    ref: {
        readonly code: number;
        readonly section: string;
        readonly name: string;
        readonly sym: unique symbol;
    }
    readonly fields: ReadonlyArray<{
        /**
         * The json path to the attribute that had a validation error
         */
        readonly field: string;
        /**
         * A description of the validation error for that attribute
         */
        readonly reason: string;
        /**
         * Index of the value passed (present only in List attribute validation errors)
         */
        readonly index: number | undefined;
        /**
         * The error thrown from the attribute's validate callback (if applicable)
         */
        readonly cause: T | undefined;
    }>
}

DynamoDB Errors

AWS Error

Code: 4001

Why this occurred: DynamoDB did not like something about your query.

What to do about it: By default ElectroDB tries to keep the stack trace close to your code, ideally this can help you identify what might be going on. A tip to help with troubleshooting: use .params() to get more insight into how your query is converted to DocClient params.

Unexpected Errors

No Owner For Pager

Code: 5004

Why this occurred: When using pagination with a Service, ElectroDB will try to identify which Entity is associated with the supplied pager. This error can occur when you supply an invalid pager, or when you are using a different pager option to a pager than what was used when retrieving it. Consult the section on Pagination to learn more.

What to do about it: If you are sure the pager you are passing to .page() is the same you received from .page() this could be an unexpected error. To mitigate the issue use the Query Option { pager: "raw" } and please open a support issue.

Pager Not Unique

Code: 5005

Why this occurred: When using pagination with a Service, ElectroDB will try to identify which Entity is associated with the supplied pager option. This error can occur when you supply a pager that resolves to more than one Entity. This can happen if your entities share the same composite attributes for the index you are querying on, and you are using the Query Option {pager: "item""}.

What to do about it: Because this scenario is possible with otherwise well considered/thoughtful entity models, the default pager type used by ElectroDB is "named". To avoid this error, you will need to use either the "raw" or "named" pager options for any index that could result in an ambiguous Entity owner.