Skip to content

fix(cli): Surface err.cause on the display paths that currently dro... (#1462)#56

Draft
aidandaly24 wants to merge 1 commit into
mainfrom
fix/1462
Draft

fix(cli): Surface err.cause on the display paths that currently dro... (#1462)#56
aidandaly24 wants to merge 1 commit into
mainfrom
fix/1462

Conversation

@aidandaly24

Copy link
Copy Markdown
Owner

Refs aws#1462

Issues

  • feat: error messages are not actionable, how to debug CDK synth failures and container build failures? aws/agentcore-cli#1462 — When CDK synth fails during agentcore import memory (or a non-TUI agentcore deploy), the user sees only "CDK synth failed: node dist/bin/cdk.js: Subprocess exited with error 1" with no actionable detail, even though the vended app printed a precise cause to stderr. There is no global --verbose/--debug flag to reveal more. (The reporter's separate complaints are weaker: container build logs for agentcore dev are already streamed inline and persisted to agentcore/.cli/logs/dev/, and cdk bootstrap is not actually a synth prerequisite, so that part is a docs/discoverability gap.)

Root cause

The actionable detail is preserved by the toolkit but dropped at the CLI's DISPLAY layer (the brief's "withErrorContext discards it" is outdated — PR aws#1459, merged 2026-06-03, the day before this issue, rewrote withErrorContext at src/cli/cdk/toolkit-lib/wrapper.ts:36-45 to mutate err.message in place and PRESERVE err.cause). Chain I verified: (1) the vended app prints a clear cause via console.error('AgentCore CDK synthesis failed:', ...) then process.exit(1) (src/assets/cdk/bin/cdk.ts:195-198); (2) @aws-cdk/toolkit-lib@1.28.0 captures that child stderr and attaches it as error.cause on the AssemblyError (node_modules/@aws-cdk/toolkit-lib/lib/api/cloud-assembly/private/exec.js:71-77), while routing the live lines through ioHost.notify as CDK_ASSEMBLY_E1002 (source-builder.js:288) — which silentIoHost no-ops (src/cli/cdk/toolkit-lib/types.ts:7-16), so nothing prints during synth; (3) synth uses silentIoHost on the import path (src/cli/commands/import/import-pipeline.ts:62) and as the synthesizeCdk default (src/cli/operations/deploy/preflight.ts:271); (4) the error then reaches a display path that drops .cause: the import catch uses err.message only (src/cli/commands/import/resource-import.ts:255) and non-TUI deploy uses getErrorMessage() which is just err.message (src/cli/errors.ts:5-7, called at src/cli/commands/deploy/actions.ts:924). Notably the TUI deploy path uses formatError() which DOES recurse err.cause (src/cli/operations/deploy/preflight.ts:45-56, used in src/cli/tui/hooks/useCdkPreflight.ts), so it is already actionable — the gap is import + non-TUI deploy. Separately, there is no global --verbose/--debug on the root command (src/cli/cli.ts:61-66, only name/description/version/-h). The reporter's bootstrap self-diagnosis is a misattribution: bin/cdk.ts synth reads local config and calls app.synth() with no AWS calls, so a missing bootstrap can never make synth fail.

The fix

Surface err.cause on the display paths that currently drop it (the wrapper already preserves it post-aws#1459): (1) in src/cli/commands/import/resource-import.ts:255 and the import-pipeline error string, append err.cause text (or reuse the existing recursive formatError from preflight.ts) so the synth child stderr reaches the user; (2) make the non-TUI deploy display (src/cli/commands/deploy/actions.ts:924 / getErrorMessage in src/cli/errors.ts) include cause, or route through formatError. (3) Optionally swap silentIoHost for a capturing IoHost during synth so the live child stderr is buffered into the per-command log file even on success-less runs. (4) Add a global --debug/--verbose on the root command (src/cli/cli.ts) that swaps silentIoHost for a verbose IoHost in synthesizeCdk/import-pipeline. (5) Docs: state cdk bootstrap is NOT a synth prerequisite (deploy auto-bootstraps with --yes), and document agentcore/.cli/logs/ plus where dev build logs live. No change needed for the dev container-build logging — already streamed (src/cli/operations/dev/container-dev-server.ts:96-124, since PR aws#500 in March 2026) and persisted (src/cli/logging/dev-logger.ts), with the log path printed at src/cli/commands/dev/command.tsx:430.

Files touched: Primary: src/cli/commands/import/resource-import.ts (catch at ~:255 + the pipeline error string in src/cli/commands/import/import-pipeline.ts:65-79) and src/cli/commands/deploy/actions.ts:924 (+ src/cli/errors.ts getErrorMessage) — surface err.cause, ideally via the existing recursive formatError in src/cli/operations/deploy/preflight.ts:45-56. Optional capture/flag: src/cli/cdk/toolkit-lib/types.ts (silentIoHost), src/cli/operations/deploy/preflight.ts:258-282 (synthesizeCdk default), src/cli/cli.ts:61-66 (global --debug). Docs: README/docs (bootstrap-not-a-synth-prereq, log directory). NOT wrapper.ts withErrorContext — it already preserves cause as of PR aws#1459.

Validation evidence

The fix was verified by reproducing the original symptom and re-running after the change:

Reproduced the symptom with the exact toolkit error shape: top-level Error message "CDK synth failed: node dist/bin/cdk.js: Subprocess exited with error 1" carrying the synth child's stderr on .cause = "AgentCore CDK synthesis failed: memory strategy "summary" requires a non-empty namespace" (mimics withErrorContext at wrapper.ts:36-45 + toolkit AssemblyError).

BEFORE FIX (old display logic): the import path (resource-import.ts:255 / import command err.message) and non-TUI deploy path (command.tsx error.message) both render ONLY "CDK synth failed: node dist/bin/cdk.js: Subprocess exited with error 1" -> .includes(causeText) === false. The synth root cause is hidden. getErrorMessage(err) likewise returns message-only, .includes(causeText) === false.

AFTER FIX: both paths route through recursive formatError, which emits:
"CDK synth failed: node dist/bin/cdk.js: Subprocess exited with error 1\n\nCaused by:\nAgentCore CDK synthesis failed: memory strategy "summary" requires a non-empty namespace"
-> formatError(err).includes(causeText) === true on both display paths. Verified three ways: (a) the new regression unit test src/cli/tests/errors.test.ts passes (33/33 in that file); (b) inline before/after simulation OVERALL PASS true; (c) the REAL production functions getErrorMessage/formatError from src/cli/errors.ts run via tsx -> getErrorMessage includes cause = false, formatError includes cause = true (REAL-SOURCE PASS true).

getErrorMessage contract unchanged (messag

Test suite: green.


Staged on the fork as a draft for human review. Promote to aws/agentcore-cli after vetting.

…ws#1462)

CDK synth failures previously showed only the generic top-level message
("CDK synth failed: ... Subprocess exited with error 1") on the import and
non-TUI deploy paths, dropping the actionable child stderr that the toolkit
wrapper preserves on err.cause.

Centralize the recursive formatError in src/cli/errors.ts (re-exported from
operations/deploy/preflight.ts for existing importers) and route the non-TUI
deploy (commands/deploy/command.tsx) and import (commands/import/command.ts)
display layers through it, so the synth root cause reaches the user. The
existing TUI deploy path already used formatError and is unchanged.
getErrorMessage contract unchanged (message-only).
@github-actions github-actions Bot added the size/s PR size: S label Jun 25, 2026
@github-actions

Copy link
Copy Markdown

Coverage Report

Status Category Percentage Covered / Total
🔵 Lines 37.16% 13593 / 36577
🔵 Statements 36.43% 14452 / 39667
🔵 Functions 31.8% 2333 / 7336
🔵 Branches 31.1% 9000 / 28932
Generated in workflow #110 for commit 07257b7 by the Vitest Coverage Report Action

@github-actions github-actions Bot added agentcore-harness-reviewing AgentCore Harness review in progress and removed agentcore-harness-reviewing AgentCore Harness review in progress labels Jun 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/s PR size: S

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant