Skip to content

Bug: Subsequent Requests without a Idempotency Key Return the Same Result as the First Request #1501

Closed
@brianhyder

Description

@brianhyder

Expected Behaviour

When an idempotency key is not provided as part of the request and the throwOnNoIdempotencyKey configuration attribute is false, the idempotency package should proceed as if it is a unique request regardless of how many times the request is sent.

Current Behaviour

When sending a request for the first time, with no idempotency key, the call succeeds and returns the proper status code along with the payload.
When sending a subsequent request, with no idempotency key, the response is the same as the response of the first request.

A cache key is still being generated but because there is no idempotency key, it is not unique.

Code snippet

const config = new IdempotencyConfig({
   hashFunction: 'md5',
   useLocalCache: false,
   expiresAfterSeconds: 3600,
   throwOnNoIdempotencyKey: false,
   eventKeyJmesPath: 'headers.idempotency-key'
});
const persistenceStore = new DynamoDBPersistenceLayer({
   tableName: 'idempotency_store',
   keyAttr: 'key'
});
makeHandlerIdempotent({ config, persistenceStore });

Steps to Reproduce

  1. Create a request where the middleware is configured as above, no idempotency key, and the response is a randomly generated value.
  2. Send the request and notate the response
  3. Verify that the record was persisted in the dynamo table
  4. Send the same request as in step 1 and note the response

The response of the second request is the same as the first response when it should be a different value since the endpoint echos random values.

Possible Solution

The issue seems to be here. When no idempotency key is passed, the value of data is null. Therefore the hash always gets calculated from the raw string #null.

private getHashedIdempotencyKey(data: Record<string, unknown>): string {
    if (this.eventKeyJmesPath) {
      data = search(data, this.eventKeyJmesPath);
    }

    if (BasePersistenceLayer.isMissingIdempotencyKey(data)) {
      if (this.throwOnNoIdempotencyKey) {
        throw new Error('No data found to create a hashed idempotency_key');
      }
      console.warn(
        `No value found for idempotency_key. jmespath: ${this.eventKeyJmesPath}`
      );
    }

    return `${this.idempotencyKeyPrefix}#${this.generateHash(
      JSON.stringify(data)
    )}`;
  }

Powertools for AWS Lambda (TypeScript) version

latest

AWS Lambda function runtime

18.x

Packaging format used

npm

Execution logs

No response

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingcompletedThis item is complete and has been merged/shippedidempotencyThis item relates to the Idempotency Utility

Type

No type

Projects

Status

Shipped

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions