Fix AWS CDK Encoded List Token String Error

Resolve the AWS CDK error 'Found an encoded list token string in a scalar string context' by using Fn::Select instead of array indexing.


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',
    });
  }
}