Skip to content

(cli tests): refactor and destroy IO expectations differ by newlines on a clean CLI checkout #2085

Closed

Description

@mkymdk

Describe the bug

On an unmodified aws/aws-cdk-cli checkout at df34416fefcbd5361b9fd3686307f718f3ac1ec1, the refactor and destroy unit tests fail against the committed IoHost recorded-output expectations. The observed differences include leading/trailing newlines in message strings.

This report concerns the test/output contract. I have not established whether the runtime output or the recorded expectations should change, and I am not claiming a deployed-resource regression.

Expected Behavior

The refactor/destroy tests pass against the committed recorded-output files on the documented supported Node.js version, without regenerating expected output simply to make the run pass.

Current Behavior

Running the two suites along with test/cli/cli.test.ts, with CI unset, produced 20 failed / 40 passed tests, two failing suites and one passing suite. The same refactor/destroy failures also occur with CI=true.

Example refactor difference:

- "message":"aws://123456789012/bermuda-triangle-1\n"
+ "message":"aws://123456789012/bermuda-triangle-1"

Example destroy difference:

- "message":"\n✅  Test-Stack-A-Display-Name: destroyed"
+ "message":"✅  Test-Stack-A-Display-Name: destroyed"

Failures include ambiguity > reports ambiguous mappings and refuses to refactor and force: true (no confirmation prompt) > destroys all top-level stacks with concurrency.

Reproduction Steps

Use a disposable checkout of aws/aws-cdk-cli at the commit above, Node.js 24.13.1 and its pinned Yarn 4.17.1. Install dependencies with corepack yarn install --immutable, then run the repository's topological corepack yarn compile (ensure the yarn shim is on PATH for child tasks). Both commands completed successfully here.

From packages/aws-cdk, run:

env -u CI TESTING_CDK=1 NODE_OPTIONS=--experimental-vm-modules \
  node ../../node_modules/jest/bin/jest.js \
  test/cli/cli.test.ts test/commands/refactor.test.ts test/commands/destroy.test.ts \
  --ci --runInBand --coverage=false

Do not pass -u / --updateSnapshot. The command exits 1. The selected tests use mocked AWS calls; no deployment is needed.

Additional Information/Context

The 20 failures reported here were reproduced on the unmodified source commit specified above.

Related implementation history: #1661 added effective-message recording and aws/aws-cdk#1686 rerouted destroy through toolkit-lib. These are context, not a claim that either PR introduced the issue. Searches of issues in both CDK repositories and matching open PRs did not find an existing report of these test failures.

Last Known Working CDK Version

Unknown; not claiming a regression from a known passing version.

CDK CLI Version

Source checkout df34416fefcbd5361b9fd3686307f718f3ac1ec1; unit tests, not a published CLI release.

Node.js Version

v24.13.1

OS

Ubuntu 24.04 / WSL2, Linux 6.6.87.2-microsoft-standard-WSL2

Language

TypeScript 5.9.3; Jest 29.

Other information

AI assistance was used in the investigation and preparation of this report. Reproduction commands were executed; no expected-output files were changed.

Activity

  1. pahud commented on Oct 23, 2026

    @pahud
    Contributor

    Hi @mkymdk,

    ┌──────────────────────────────────────────────────────────────┐
    │ 🔴 Reported State                                            │
    │ refactor/destroy IO snapshots fail on a clean checkout       │
    │ (leading/trailing \n differ); CI on main is green            │
    └──────────────────────────────┬───────────────────────────────┘
                                   │
                                   ▼
    ┌──────────────────────────────────────────────────────────────┐
    │ 🔍 Root Cause                                                │
    │ trim() in toolkit-lib can't see \n inside ANSI codes; nx     │
    │ sets FORCE_COLOR in CI, direct jest runs have no color       │
    └──────────────────────────────┬───────────────────────────────┘
                                   │
                                   ▼
    ┌──────────────────────────────────────────────────────────────┐
    │ 🟢 Suggested Fix                                             │
    │ Pin color (FORCE_COLOR / chalk.level) in the jest setup      │
    └──────────────────────────────────────────────────────────────┘
    

    Thanks for the careful report. I reproduced it on df34416 with your exact command (20 failed / 40 passed). With FORCE_COLOR=1, all 60 pass, so the snapshots depend on whether chalk has color enabled.

    toolkit-lib trims every message, but with color on the \n sits inside the ANSI codes, so trim() leaves it alone. The recorder then strips the ANSI codes and the \n shows up:

    export function withTrimmedWhitespace(ioHost: IIoHost): IIoHost {
    return {
    notify: async <T>(msg: IoMessage<T>) => {
    await ioHost.notify({
    ...msg,
    message: msg.message.trim(),
    });
    },
    requestResponse: async <T, U>(msg: IoRequest<T, U>) => {
    return ioHost.requestResponse({
    ...msg,
    message: msg.message.trim(),
    });
    },
    };
    }

    CI runs the tests through nx run-many, which sets FORCE_COLOR=true for each task. That's why the committed snapshots pass there but not in a direct jest run. Pinning color in the aws-cdk jest setup would make the run deterministic. A PR is welcome if you're interested.

    This belongs in aws/aws-cdk-cli, so we'll transfer it there. Marking this as a p2 bug.

  2. transferred this issue fromaws/aws-cdkon Oct 23, 2026
  3. mkymdk commented on Oct 24, 2026

    @mkymdk
    ContributorAuthor

    Thanks @pahud for reproducing this and explaining the color-dependent behavior! I see that #2047 already addresses this. Thanks to @lazerg for the fix as well.

  4. added a commit that references this issue on Oct 29, 2026
    f9172c7
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions