![[AWS CDK] synthesize 実行時に “Error: Expected JSON path to start with ‘$’, got: DISCARD” というエラーが発生する場合の対処](https://devio2023-media.developers.io/wp-content/uploads/2022/08/aws-step-functions.png)
[AWS CDK] synthesize 実行時に “Error: Expected JSON path to start with ‘$’, got: DISCARD” というエラーが発生する場合の対処
この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
こんにちは、CX事業本部 Delivery部の若槻です。
今回は、AWS CDK での synthesize(合成)実行時に Error: Expected JSON path to start with '$', got: DISCARD というエラーが発生する場合の対処についてです。
DISCARD とは
AWS CDK で AWS Step Functions ステートマシンを定義する際に、inputPathやoutputPath、resultPathに特殊文字列の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 コードで使用してみます。
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を指定したresultPathでnullが指定されました。
{
  "StartAt": "pass1",
  "States": {
    "pass1": {
      "Type": "Pass",
      "ResultPath": null,
      "Next": "pass2"
    },
    "pass2": {
      "Type": "Pass",
      "ResultPath": null,
      "End": true
    }
  }
}
ここで、pass1で指定したaws_stepfunctions.JsonPath.DISCARDとpass2で指定した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を指定するように変更すると解決できました。
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.DISCARDはnullに変換できなくなったようです。
おわりに
AWS CDK での synthesize 実行時に Error: Expected JSON path to start with '$', got: DISCARD というエラーが発生する場合の対処についてでした。
aws_stepfunctions.JsonPath.DISCARDとするべきところをaws_stepfunctions.DISCARDとしていたことが原因でした。このエラーのせいで CDK バージョンをアップグレードできていない環境があったので、対処方法が分かって良かったです。
参考
以上








