Home > Net >  AWS Lambda error "iam property does not exist" when accessing iam Cognito attribute that I
AWS Lambda error "iam property does not exist" when accessing iam Cognito attribute that I

Time:11-12

I am getting an error while trying to access an object that I know exists.

When trying to access the iam property of the event.authorizer object returned from AWS Cognito, an error displays in both VS Code and the terminal once I run it.

src/private.ts:9:33 - error TS2339: Property 'iam' does not exist on type '{ jwt: { claims: { [name: string]: string | number | boolean | string[]; }; scopes: string[]; }; }'.ts(2339)

This error is especially puzzling, because when I print the "event" object, it shows evidence that it exists.

Output of event.requestContext:

{"statusCode":200,"headers":{"Content-type":"text/json"},"body":"{\"event\":{\"accountId\":\"365416766059\",\"apiId\":\"8ihwuguj40\",\"authorizer\":{\"iam\":{\"accessKey\":\"ASIAVKFE... 1068 more characters"}

This shows that there is an object iam that is the value of the authorizer attribute. This is proof that it exists. So why does VS Code have an issue with it?


I ran the code using npx sst start which runs the code with no issues, and returns the expected event object with authorizer and awt nested objects.

Full code for lambda function is below.

import { APIGatewayProxyHandlerV2 } from "aws-lambda"

export const handler: APIGatewayProxyHandlerV2 = async (event) => {
  const rand = Math.floor(Math.random() * 10)

  const authoriser = event.requestContext.authorizer


  const accountId = authoriser?.iam.accountId ?? "" // Problem starts with reference to "iam" here.
 

  return {
    statusCode: 200,
    headers: {"Content-type": "text/json"},
    body: JSON.stringify({ message: `Private random number: ${rand}`, accountId: accountId}),
  }
}

I have tried:

  • Making iam an optional by appending a question mark.
  • Using a try-catch block around the statement.

CodePudding user response:

event is mis-typed.

By typing your function as APIGatewayProxyHandlerV2, you have told typescript that event is of type APIGatewayProxyEventV2 (typedef here). The actual event from Lambda you are getting is not that type, as evident from the log output.

// what typescript thinks your event is:
export interface APIGatewayProxyEventV2 {
    version: string;
    routeKey: string;
    rawPath: string;
    rawQueryString: string;
    cookies?: string[] | undefined;
    headers: APIGatewayProxyEventHeaders;
    queryStringParameters?: APIGatewayProxyEventQueryStringParameters | undefined;
    requestContext: {
        accountId: string;
        apiId: string;
        authorizer?: {
            jwt: {
                claims: { [name: string]: string | number | boolean | string[] };
                scopes: string[];
            };
        } | undefined;
        domainName: string;
        domainPrefix: string;
        ...etc

So you need to fix the event type. What are your options?

  1. Search for a pre-defined type that matches the lambda event
  2. Be lazy and self-hating: event: any
  3. Define a minimum type that satisfies the contract: event: MyLambdaEvent
// custom event type
// match the required parts of the event object lambda is actually giving you
interface MyLambdaEvent {
  authorizer: {
    iam: {
      accountId: string
    }
  }
}
  • Related