[Error] Add a Create Note API (Cannot read property 'hash' of undefined)

Add a Create Note API
Hello, I recently stumbled upon this amazing resource and started working on it, I finished the full CRUD API successfully, and it works great! However, whenever I execute serverless invoke local --function create --path mocks/create-event.json

Serverless: DOTENV: Could not find .env file.
Serverless: Bundling with Webpack...
[hardsource:b7bd9ddf] Could not freeze /home/admin/Desktop/scratch-application-api/create.js: Cannot read property 'hash' of undefined
{
    "statusCode": 200,
    "headers": {
        "Access-Control-Allow-Origin": "*",
        "Access-Control-Allow-Credentials": true
    },
    "body": "{\"userId\":\"USER-SUB-1234\",\"noteId\":\"f5a127a0-8e62-11ea-9c7e-5d896381e2b3\",\"content\":\"hello world\",\"attachment\":\"hello.jpg\",\"createdAt\":1588636626714}"
}

The invocation still ends up going through and I can see my new entry in my DynamoDB table. However, I don’t know if I should keep going like this and deploy my API on AWS. Let me know if you have encountered the same problem before!

# NOTE: update this with your service name
service: scratch-application-api

# Create an optimized package for our functions
package:
  individually: true

plugins:
  - serverless-bundle # Package our functions with Webpack
  - serverless-offline
  - serverless-dotenv-plugin # Load .env as environment variables

provider:
  name: aws
  runtime: nodejs12.x
  stage: prod
  region: us-east-2

  # These environment variables are made available to our functions
  # under process.env.
  environment:
    tableName: scratch-notes

  # 'iamRoleStatements' defines the permission policy for the Lambda function.
  # In this case Lambda functions are granted with permissions to access DynamoDB.
  iamRoleStatements:
    - Effect: Allow
      Action:
        - dynamodb:DescribeTable
        - dynamodb:Query
        - dynamodb:Scan
        - dynamodb:GetItem
        - dynamodb:PutItem
        - dynamodb:UpdateItem
        - dynamodb:DeleteItem
      Resource: "arn:aws:dynamodb:us-east-2:269799803939:table/scratch-notes"

functions:
  # Defines an HTTP API endpoint that calls the main function in create.js
  # - path: url path is /notes
  # - method: POST request
  # - cors: enabled CORS (Cross-Origin Resource Sharing) for browser cross
  #     domain api call
  # - authorizer: authenticate using the AWS IAM role
  create:
    handler: create.main
    events:
      - http:
          path: scratch-notes
          method: post
          cors: true
          authorizer: aws_iam
  get:
    # Defines an HTTP API endpoint that calls the main function in get.js
    # - path: url path is /notes/{id}
    # - method: GET request
    handler: get.main
    events:
      - http:
          path: scratch-notes/{id}
          method: get
          cors: true
          authorizer: aws_iam
  list:
    # Defines an HTTP API endpoint that calls the main function in list.js
    # - path: url path is /notes
    # - method: GET request
    handler: list.main
    events:
      - http:
          path: scratch-notes
          method: get
          cors: true
          authorizer: aws_iam
  delete:
    # Defines an HTTP API endpoint that calls the main function in delete.js
    # - path: url path is /notes/{id}
    # - method: DELETE request
    handler: delete.main
    events:
      - http:
          path: scratch-notes/{id}
          method: delete
          cors: true
          authorizer: aws_iam
import * as uuid from "uuid";
import handler from "./libs/handler-lib";
import dynamoDb from "./libs/dynamodb-lib";

export const main = handler(async (event, context) => {
  const data = JSON.parse(event.body);
  const params = {
    TableName: process.env.tableName,
    // 'Item' contains the attributes of the item to be created
    // - 'userId': user identities are federated through the
    //             Cognito Identity Pool, we will use the identity id
    //             as the user id of the authenticated user
    // - 'noteId': a unique uuid
    // - 'content': parsed from request body
    // - 'attachment': parsed from request body
    // - 'createdAt': current Unix timestamp
    Item: {
      userId: event.requestContext.identity.cognitoIdentityId,
      noteId: uuid.v1(),
      content: data.content,
      attachment: data.attachment,
      createdAt: Date.now()
    }
  };

  await dynamoDb.put(params);

  return params.Item;
});

I’m experiencing the same error message for a similar use case. Googling the issue brought me back here. Not exactly sure what is going on here, but the code seems to execute and run just fine despite the console message.

EDIT: It looks like this is coming out of webpack, which serverless-bundle uses. As a total hail mary, I updated/reinstalled serverless-bundle and the error went away. Maybe it will work for you?

npm install --save-dev serverless-bundle

4 Likes

I had the same issue and it went away with your proposed solution. Thank you @SethThomas

2 Likes

I tried the same; at first it didn’t work, though then I realized that there was a .webpack folder in my project root which I figured could be affecting the invocations. Removed that and it worked!