Skip to content

fix: fallback to legacy stack name in deployed state - #2248

Open
nborges-aws wants to merge 2 commits into
refactorfrom
deployed-state-fix
Open

fix: fallback to legacy stack name in deployed state#2248
nborges-aws wants to merge 2 commits into
refactorfrom
deployed-state-fix

Conversation

@nborges-aws

Copy link
Copy Markdown
Contributor

Description

The refactored CLI updated deployedState.ts to track stackArn, where our legacy/main deployedState.ts instead tracked stackName. Therefore, inspecting a legacy project with the new CLI resulted in deployed resources showing as 'local-only'.

This PR addresses this concern by adding stackName as a fallback in our resource resolution logic. This change allows legacy projects to be inspected correctly through the new CLI, without the need for redeploying resources.

Example

This example shows a legacy project with two deployed harnesses in the project. The recording shows the following commands:

  • agentcore -> this is the currently released RC of our refactor branch installed via npm.
  • acr-dev -> alias pointing to my local clone and dev workspace of the CLI. Built from refactor branch including the changes present in this PR
Screen.Recording.2026-09-08.at.11.52.03.AM.mov

Type of Change

  • Bug fix
  • New feature
  • Breaking change
  • Documentation update
  • Other (please describe):

Testing

How have you tested the change?

Manually verified as shown in screen recording above. Additionally, added a unit test asserting that a legacy stack name is resolved correctly when the target does not have a stack ARN. Focused unit test passed.

  • bun run test (3180 pass, 0 fail)
  • I ran npm run test:unit and npm run test:integ
  • I ran npm run typecheck
  • I ran npm run lint
  • If I modified src/assets/, I ran npm run test:update-snapshots and committed the updated snapshots

Checklist

  • I have read the CONTRIBUTING document
  • I have added any necessary tests that prove my fix is effective or my feature works
  • I have updated the documentation accordingly
  • I have added an appropriate example to the documentation to outline the feature, or no new docs are needed
  • My changes generate no new warnings
  • Any dependent changes have been merged and published

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the
terms of your choice.

@github-actions github-actions Bot added the size/s PR size: S label Sep 8, 2026
@agentcore-devx-automation agentcore-devx-automation Bot added claude-security-reviewing Claude Code /security-review in progress agentcore-harness-reviewing AgentCore Harness review in progress labels Sep 8, 2026
@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automation agentcore-devx-automation Bot removed the claude-security-reviewing Claude Code /security-review in progress label Sep 8, 2026

@agentcore-devx-automation agentcore-devx-automation Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AgentCore Harness Review

Verdict: Looks good

The fix is small, focused, and correct:

  • ResourceStateSchema.stackName is added as optional, so pre-existing legacy state files continue to parse and — thanks to the surrounding passthrough() — the value is preserved across read-modify-write cycles until a new deploy records a stackArn that will shadow it.
  • Both resolveDeployedResources and resolveProjectResources fall back to recorded.resources.stackName only when stackArn is absent, which matches the "legacy → new" upgrade direction. describeStack accepts either a name or ARN, so the fallback works without further changes.
  • I checked the other callers of readDeployedState in cdk.ts (the credentials read at line 223 and teardown) — neither depends on the stack reference in a way that needs the same fallback, so the change is complete.
  • Tests exercise the new legacy path via the real deployed-state.json (temp dir + updateTargetState), only mocking the stack describer, which is the right seam.

Nothing blocking from me.

@agentcore-devx-automation agentcore-devx-automation Bot removed the agentcore-harness-reviewing AgentCore Harness review in progress label Sep 8, 2026
@codecov-commenter

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 97.04%. Comparing base (d9ab959) to head (19c5eef).
⚠️ Report is 1 commits behind head on refactor.

Additional details and impacted files
@@            Coverage Diff            @@
##           refactor    #2248   +/-   ##
=========================================
  Coverage     97.04%   97.04%           
=========================================
  Files           566      566           
  Lines         39409    39412    +3     
=========================================
+ Hits          38244    38247    +3     
  Misses         1165     1165           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@aidandaly24 aidandaly24 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One small nit but looks good to me

const { spec } = project;
const deployedState = await readDeployedState(this.json, project.rootPath);
const recorded = deployedState.targets[target.name];
const stackReference = recorded?.stackArn ?? recorded?.resources?.stackName;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Would it make sense to pull this fallback into deployedState.ts next to the field it reads, something like stackReferenceOf(recorded)? The same expression now appears here and in resolveProjectResources, and the reason it exists is only explained by the schema comment on stackName. Keeping the legacy rule beside the schema means the next reader of the stack binding, like the delete-and-recreate check the stackArn comment describes, gets the fallback without having to know it exists.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1

});

test("fails without reading AWS when the target has no deployed stack ARN", async () => {
test("resolves resources from a legacy stack name when the target has no stack ARN", async () => {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These tests appear to be asserting on implementations rather than behaviors. Would it be possible to test at the handler level, such that we create a project, insert the legacy stackName field into deployedState, then ensure the status command works as expected?

const { spec } = project;
const deployedState = await readDeployedState(this.json, project.rootPath);
const recorded = deployedState.targets[target.name];
const stackReference = recorded?.stackArn ?? recorded?.resources?.stackName;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1

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.

4 participants