Skip to content

fix: Report every YAML alias in W1101, including scalars - #4724

Merged
kddejong merged 1 commit into
aws-cloudformation:mainfrom
esetnik:fix/issue/4721
Sep 28, 2026
Merged

kddejong merged 1 commit into
aws-cloudformation:mainfrom
esetnik:fix/issue/4721

Conversation

@esetnik

@esetnik esetnik commented Sep 23, 2026

Copy link
Copy Markdown
Contributor

Issue #, if available:

Fixes #4721

Description of changes:

W1101 already warns about YAML aliases, but it finds them by object identity (a mapping or sequence reachable from two places). That misses scalar aliases entirely, so this template lints clean while CloudFormation rejects it with Template error: YAML aliases are not allowed in CloudFormation templates:

AWSTemplateFormatVersion: "2010-09-09"
Resources:
  FirstLogGroup:
    Type: AWS::Logs::LogGroup
    Properties:
      RetentionInDays: &Retention 30
  SecondLogGroup:
    Type: AWS::Logs::LogGroup
    Properties:
      RetentionInDays: *Retention
$ cfn-lint template.yaml   # before: exit 0
$ cfn-lint template.yaml   # after
W1101 YAML alias '*Retention' is rejected by CloudFormation unless the template is first processed by the 'package' cli command or AWS SAM
template.yaml:10:24

Changes:

  • cfn_yaml.loads still resolves aliases exactly as before. When the source contains & (the same gate _guard_alias_expansion uses), it also scans the tokens for aliases and records each one's name, location and template path on the root node. Recording happens after the expansion guard, so recursive or amplified aliases are still rejected first.
  • Template copies that list in __init__, because transforms (SAM, LanguageExtensions) replace cfn.template.
  • W1101 reports one warning per alias at the alias itself, with the path, so resource-level ignore_checks still work. It returns nothing for templates with Transform: AWS::Serverless-2016-10-31, since those are deployed with the SAM CLI, which expands aliases client-side.

Behaviour changes for existing users: the W1101 message now names the alias, each use of an alias is reported (previously only the first shared container), and SAM templates no longer get W1101. The yaml-alias snapshot only changes in message and column range; its path is the same.

Tests: new rule, decoder and end-to-end tests (scalar, sequence, merge key, SAM, LanguageExtensions), a good SAM fixture and a new integration snapshot for the repro. tox -e py310,py314,style passes.

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

🤖 Generated with Claude Code

W1101 found aliases by object identity, which only works for mappings
and sequences, so a scalar alias such as `RetentionInDays: *Retention`
passed cleanly even though CloudFormation rejects the template.

The YAML loader now records each alias token with its location and
template path (only when the source contains "&"), Template captures
them before transforms run, and W1101 reports one warning per alias at
the alias itself. Aliases are still resolved as before. Templates using
the AWS::Serverless-2016-10-31 transform are skipped, since the SAM CLI
expands aliases client-side.

Fixes aws-cloudformation#4721

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@kddejong kddejong 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.

Approving. Verified locally against the branch.

  • Repro from #4721 now emits W1101 at the alias; SAM templates are correctly skipped; AWS::LanguageExtensions still reports.
  • The #4697 ForEach false-positive test still passes; a literal * in a quoted string doesn't false-positive.
  • 20 new tests pass, ruff check/format clean.

Token-scan is the right approach since the loader resolves aliases during compose, and capturing them in Template.__init__ before transforms swap out self.template is a nice catch.

One note for visibility (non-blocking): this changes W1101's message/column and now reports every alias use, so the snapshot update is expected.

@codecov

codecov Bot commented Sep 28, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 88.67925% with 6 lines in your changes missing coverage. Please review.
✅ Project coverage is 94.73%. Comparing base (9e86699) to head (4f54a90).
⚠️ Report is 2 commits behind head on main.

Files with missing lines Patch % Lines
src/cfnlint/decode/cfn_yaml.py 87.75% 3 Missing and 3 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #4724      +/-   ##
==========================================
- Coverage   94.78%   94.73%   -0.05%     
==========================================
  Files         439      439              
  Lines       15805    15836      +31     
  Branches     3055     3059       +4     
==========================================
+ Hits        14980    15003      +23     
- Misses        450      455       +5     
- Partials      375      378       +3     
Flag Coverage Δ
unittests 94.73% <88.67%> (-0.05%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ 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.

@kddejong
kddejong merged commit 21d7e07 into aws-cloudformation:main Sep 28, 2026
20 of 21 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

No error for YAML aliases, which CloudFormation rejects ("YAML aliases are not allowed")

2 participants