[AWS CDK] synthesize 実行時に “Error: Expected JSON path to start with ‘$’, got: DISCARD” というエラーが発生する場合の対処

2023.04.30

こんにちは、CX事業本部 Delivery部の若槻です。

今回は、AWS CDK での synthesize(合成)実行時に Error: Expected JSON path to start with '$', got: DISCARD というエラーが発生する場合の対処についてです。

DISCARD とは

AWS CDK で AWS Step Functions ステートマシンを定義する際に、inputPathoutputPathresultPathに特殊文字列のDISCARDを指定することにより、不要なデータをパスに追加せずに破棄することができます。

Instead of a JSON path string, each of these paths can also have the special value JsonPath.DISCARD, which causes the corresponding indexing expression to return an empty object ({}). Effectively, that means there will be an empty input object, an empty result object, no effect on the state, or an empty state, respectively.

これにより不要なデータがステート間で引き継がれないようになるため、実行履歴の可読性向上や、処理の効率化に役立ちます。

実際に CDK コードで使用してみます。

lib/cdk-sample-app.ts

import { Construct } from 'constructs';
import { aws_stepfunctions, Stack, StackProps } from 'aws-cdk-lib';

export class CdkSampleStack extends Stack {
  constructor(scope: Construct, id: string, props: StackProps) {
    super(scope, id, props);

    const pass1 = new aws_stepfunctions.Pass(this, 'pass1', {
      resultPath: aws_stepfunctions.JsonPath.DISCARD,
    });

    const pass2 = new aws_stepfunctions.Pass(this, 'pass2', {
      resultPath: aws_stepfunctions.DISCARD,
    });

    new aws_stepfunctions.StateMachine(this, 'StateMachine', {
      definition: pass1.next(pass2),
    });
  }
}

cdk synth コマンドを実行して CloudFormation テンプレートを生成すると、ステートマシンの定義は次のようになります。pass1およびpass2ともにDISCARDを指定したresultPathnullが指定されました。

definition

{
  "StartAt": "pass1",
  "States": {
    "pass1": {
      "Type": "Pass",
      "ResultPath": null,
      "Next": "pass2"
    },
    "pass2": {
      "Type": "Pass",
      "ResultPath": null,
      "End": true
    }
  }
}

ここで、pass1で指定したaws_stepfunctions.JsonPath.DISCARDpass2で指定したaws_stepfunctions.DISCARDのいずれでもnullを指定できているのですが、このことが後述の事象に繋がります。

事象

CDK ライブラリを最新版にアップグレードしました。

npm i aws-cdk aws-cdk-lib

すると、cdk synth コマンド実行時にExpected JSON path to start with '$', got: DISCARDというエラーが発生するようになりました。

$ npx cdk synth
(中略)

Error: Expected JSON path to start with '$', got: DISCARD
    at Object.renderJsonPath (/Users/wakatsuki.ryuta/projects/cm-rwakatsuki/cdk_sample_app/node_modules/aws-cdk-lib/aws-stepfunctions/lib/states/state.js:1:8277)
    at Pass.toStateJson (/Users/wakatsuki.ryuta/projects/cm-rwakatsuki/cdk_sample_app/node_modules/aws-cdk-lib/aws-stepfunctions/lib/states/pass.js:1:1512)
    at StateGraph.toGraphJson (/Users/wakatsuki.ryuta/projects/cm-rwakatsuki/cdk_sample_app/node_modules/aws-cdk-lib/aws-stepfunctions/lib/state-graph.js:1:1915)
    at new StateMachine (/Users/wakatsuki.ryuta/projects/cm-rwakatsuki/cdk_sample_app/node_modules/aws-cdk-lib/aws-stepfunctions/lib/state-machine.js:1:5166)
    at new CdkSampleStack (/Users/wakatsuki.ryuta/projects/cm-rwakatsuki/cdk_sample_app/lib/cdk-sample-app.ts:16:5)
    at Object.<anonymous> (/Users/wakatsuki.ryuta/projects/cm-rwakatsuki/cdk_sample_app/bin/cdk_sample_app.ts:6:1)
    at Module._compile (node:internal/modules/cjs/loader:1105:14)
    at Module.m._compile (/Users/wakatsuki.ryuta/projects/cm-rwakatsuki/cdk_sample_app/node_modules/ts-node/src/index.ts:1618:23)
    at Module._extensions..js (node:internal/modules/cjs/loader:1159:10)
    at Object.require.extensions.<computed> [as .ts] (/Users/wakatsuki.ryuta/projects/cm-rwakatsuki/cdk_sample_app/node_modules/ts-node/src/index.ts:1621:12)

Subprocess exited with error 1

対処方法

先に対処方法についてですが、aws_stepfunctions.DISCARDではなくaws_stepfunctions.JsonPath.DISCARDを指定するように変更すると解決できました。

lib/cdk-sample-app.ts

import { Construct } from 'constructs';
import { aws_stepfunctions, Stack, StackProps } from 'aws-cdk-lib';

export class CdkSampleStack extends Stack {
  constructor(scope: Construct, id: string, props: StackProps) {
    super(scope, id, props);

    const pass1 = new aws_stepfunctions.Pass(this, 'pass1', {
      resultPath: aws_stepfunctions.JsonPath.DISCARD,
    });

    const pass2 = new aws_stepfunctions.Pass(this, 'pass2', {
-      resultPath: aws_stepfunctions.DISCARD,
+      resultPath: aws_stepfunctions.JsonPath.DISCARD,
    });

    new aws_stepfunctions.StateMachine(this, 'StateMachine', {
      stateMachineName: 'StateMachine',
      definition: pass1.next(pass2),
    });
  }
}

以降、cdk synth コマンド実行時に同エラーは発生しなくなりました。

調査、原因

CDK ライブラリのどのリリースバージョンで同エラーが再現するか調べてみると、v2.68.0以前のリリースでは発生せず、v2.69.0以降のリリースで発生することがわかりました。

v2.69.0のリリースノートを確認すると、以下のようにaws_stepfunctionsの仕様が変更されています。

Bug Fixes - sfn: can't override toStateJson() from other languages (#24593) (e955d18), closes #14639

上記変更のプルリクエストは以下になります。nullという JSON 表現が多言語 API でも使えるように修正されています。

これによりaws_stepfunctions.DISCARDnullに変換できなくなったようです。

おわりに

AWS CDK での synthesize 実行時に Error: Expected JSON path to start with '$', got: DISCARD というエラーが発生する場合の対処についてでした。

aws_stepfunctions.JsonPath.DISCARDとするべきところをaws_stepfunctions.DISCARDとしていたことが原因でした。このエラーのせいで CDK バージョンをアップグレードできていない環境があったので、対処方法が分かって良かったです。

参考

以上