Description
troubleshoot_cloudformation_deployment (in cloudformation_deployment_troubleshooter.py) always returns an empty cloudformation_events list — even for a stack that is clearly in a failed state (UPDATE_ROLLBACK_COMPLETE) — because it never scopes the describe_events call to the operation that actually failed.
Root cause
# src/aws-iac-mcp-server/awslabs/aws_iac_mcp_server/tools/cloudformation_deployment_troubleshooter.py
stacks = self.cfn_client.describe_stacks(StackName=stack_name)['Stacks']
...
response['raw_data']['stack_status'] = stacks[0].get('StackStatus')
...
cloudformation_events = self.cfn_client.describe_events(
StackName=stack_name, Filters={'FailedEvents': True}
)['OperationEvents']
Per the DescribeEvents docs, CloudFormation groups events by Operation ID — every rollback, update, etc. is its own operation. DescribeStacks now returns a LastOperations array, e.g.:
"LastOperations": [
{"OperationType": "ROLLBACK", "OperationId": "d0f12313-..."},
{"OperationType": "UPDATE_STACK", "OperationId": "1c211b5a-..."}
]
The failed resource events live under the UPDATE_STACK (or CREATE_STACK) operation — not the ROLLBACK operation, since the rollback itself typically succeeds. The tool reads describe_stacks only for StackStatus, discards LastOperations, and then calls describe_events with just StackName and no OperationId. Without an explicit OperationId, FailedEvents=true appears to scope to the latest operation only (the successful ROLLBACK), so it finds nothing — even though the preceding UPDATE_STACK operation has failed events available via describe-events --operation-id <id> --filter FailedEvents=true.
Reproduced against 1.0.11 and confirmed the bug is still present at main (current 1.0.20) — the file has had no relevant changes since it was introduced in #1836.
Steps to reproduce
- Trigger a CloudFormation stack update that fails and rolls back to
UPDATE_ROLLBACK_COMPLETE.
- Call
troubleshoot_cloudformation_deployment(stack_name=..., region=...).
- Observe
raw_data.stack_status correctly shows UPDATE_ROLLBACK_COMPLETE, but raw_data.cloudformation_events, matched_failures, and failed_event_count are all empty/zero, giving no indication of what actually failed.
Expected behavior
The tool should:
- Read
LastOperations from the describe_stacks response.
- Identify the failed operation (the one preceding a
ROLLBACK, or the operation itself if it's a CREATE/UPDATE that failed without rollback).
- Call
describe_events(OperationId=<that operation id>, Filters={'FailedEvents': True}) to retrieve the actual failed resource events.
Environment
- Package:
awslabs.aws-iac-mcp-server
- Version tested:
1.0.11 (bug also present at main / 1.0.20)
- AWS CLI/SDK: boto3 CloudFormation
describe_events/describe_stacks
Suggested fix
stacks = self.cfn_client.describe_stacks(StackName=stack_name)['Stacks']
stack = stacks[0]
response['raw_data']['stack_status'] = stack.get('StackStatus')
# Pick the most recent non-rollback operation to find what actually failed
last_operations = stack.get('LastOperations', [])
operation_id = next(
(op['OperationId'] for op in last_operations if op.get('OperationType') != 'ROLLBACK'),
last_operations[0]['OperationId'] if last_operations else None,
)
describe_events_kwargs = {'Filters': {'FailedEvents': True}}
if operation_id:
describe_events_kwargs['OperationId'] = operation_id
else:
describe_events_kwargs['StackName'] = stack_name
cloudformation_events = self.cfn_client.describe_events(**describe_events_kwargs)['OperationEvents']
Happy to submit a PR with this fix if that's useful — wanted to file the issue first in case there's context I'm missing about why StackName-only scoping was chosen.
Description
troubleshoot_cloudformation_deployment(incloudformation_deployment_troubleshooter.py) always returns an emptycloudformation_eventslist — even for a stack that is clearly in a failed state (UPDATE_ROLLBACK_COMPLETE) — because it never scopes thedescribe_eventscall to the operation that actually failed.Root cause
Per the
DescribeEventsdocs, CloudFormation groups events by Operation ID — every rollback, update, etc. is its own operation.DescribeStacksnow returns aLastOperationsarray, e.g.:The failed resource events live under the
UPDATE_STACK(orCREATE_STACK) operation — not theROLLBACKoperation, since the rollback itself typically succeeds. The tool readsdescribe_stacksonly forStackStatus, discardsLastOperations, and then callsdescribe_eventswith justStackNameand noOperationId. Without an explicitOperationId,FailedEvents=trueappears to scope to the latest operation only (the successfulROLLBACK), so it finds nothing — even though the precedingUPDATE_STACKoperation has failed events available viadescribe-events --operation-id <id> --filter FailedEvents=true.Reproduced against
1.0.11and confirmed the bug is still present atmain(current1.0.20) — the file has had no relevant changes since it was introduced in #1836.Steps to reproduce
UPDATE_ROLLBACK_COMPLETE.troubleshoot_cloudformation_deployment(stack_name=..., region=...).raw_data.stack_statuscorrectly showsUPDATE_ROLLBACK_COMPLETE, butraw_data.cloudformation_events,matched_failures, andfailed_event_countare all empty/zero, giving no indication of what actually failed.Expected behavior
The tool should:
LastOperationsfrom thedescribe_stacksresponse.ROLLBACK, or the operation itself if it's aCREATE/UPDATEthat failed without rollback).describe_events(OperationId=<that operation id>, Filters={'FailedEvents': True})to retrieve the actual failed resource events.Environment
awslabs.aws-iac-mcp-server1.0.11(bug also present atmain/1.0.20)describe_events/describe_stacksSuggested fix
Happy to submit a PR with this fix if that's useful — wanted to file the issue first in case there's context I'm missing about why
StackName-only scoping was chosen.