Fix error: Found an encoded list token string in a scalar string context in AWS CDK

Solve the error: Found an encoded list token string in a scalar string context in AWS CDK

ยท

2 min read

The error throw new Error: Found an encoded list token string in a scalar string context. Use 'Fn.select(0, list)' (not 'list[0]') to extract elements from token lists. likely happens if you do the following:

  • You try to fetch an element from a list token string using the index from an array method e.g. list[0].

This is how the error arises when we put it in the context of AWS CDK as shown in the example below:

import * as cdk from 'aws-cdk-lib';
import * as ec2 from 'aws-cdk-lib/aws-ec2';

declare const vpc: ec2.Vpc;

export class MyCdkStack extends cdk.Stack {
  constructor(scope: cdk.App, id: string, props: cdk.StackProps) {
    super(scope, id, props);

    const exampleInterfaceVpcEndPoint = new ec2.InterfaceVpcEndpoint(
      this,
      'exampleInterfaceVpcEndPoint',
      {
        vpc: vpc,
        service: new ec2.InterfaceVpcEndpointService(
          'com.amazonaws.vpce.eu-west-1.vpce-svc-87944eb12b01f2afe'
        ),
      }
    );

    new cdk.CfnOutput(this, 'exampleInterfaceVpcEndPointDnsEntryName', {
      // Using the TypeScript index style to fetch the first element wont work
      // as shown in the value of this example ๐Ÿ‘‡
      value: exampleInterfaceVpcEndPoint.vpcEndpointDnsEntries[0],
      description: 'First DNS entry for the VPC Interface endpoint',
      exportName: 'exampleInterfaceVpcEndPointDnsEntry',
    });
  }
}

In order to fix the error in AWS CDK, you need to use the CloudFormation intrinsic function Fn::Select. This returns a single object from a list of objects by index. In AWS CDK you do that by using this method: cdk.Fn.select(index: number, array: string[]): string

To solve the error, you can do the following as shown in the AWS CDK Stack example:

import * as cdk from 'aws-cdk-lib';
import * as ec2 from 'aws-cdk-lib/aws-ec2';

declare const vpc: ec2.Vpc;

export class MyCdkStack extends cdk.Stack {
  constructor(scope: cdk.App, id: string, props: cdk.StackProps) {
    super(scope, id, props);

    const exampleInterfaceVpcEndPoint = new ec2.InterfaceVpcEndpoint(
      this,
      'exampleInterfaceVpcEndPoint',
      {
        vpc: vpc,
        service: new ec2.InterfaceVpcEndpointService(
          'com.amazonaws.vpce.eu-west-1.vpce-svc-87944eb12b01f2afe'
        ),
      }
    );

    new cdk.CfnOutput(this, 'exampleInterfaceVpcEndPointDnsEntryName', {
      // This is the correct way to select
      // an element from a list token string ๐Ÿ‘‡
      value: cdk.Fn.select(
        0,
        exampleInterfaceVpcEndPoint.vpcEndpointDnsEntries
      ),
      description: 'First DNS entry for the VPC Interface endpoint',
      exportName: 'exampleInterfaceVpcEndPointDnsEntry',
    });
  }
}

Originally posted on Towards the Cloud

If you liked this post, then you can subscribe to my newsletter