Skip to content

feat: Add rule W4002 for parameters missing from Metadata Interface#4526

Open
johnanand707 wants to merge 2 commits into
aws-cloudformation:mainfrom
johnanand707:fix/issue/4115-w4002-parameter-not-in-interface
Open

feat: Add rule W4002 for parameters missing from Metadata Interface#4526
johnanand707 wants to merge 2 commits into
aws-cloudformation:mainfrom
johnanand707:fix/issue/4115-w4002-parameter-not-in-interface

Conversation

@johnanand707

Copy link
Copy Markdown
Contributor

Issue #, if available: Closes #4115

Description of changes:

Adds a new warning rule W4002 that implements the inverse check of W4001.

  • W4001 warns when a parameter referenced in Metadata.AWS::CloudFormation::Interface does not exist in the Parameters section.
  • W4002 warns when a declared Parameter is not listed in any ParameterGroup, so it would not appear in the CloudFormation Console UI.

Changes:

  • src/cfnlint/rules/metadata/InterfaceParameterInGroup.py — new rule (49 lines)
  • test/unit/rules/metadata/test_interface_parameter_in_group.py — 5 parametrized unit tests covering the all-grouped, partial, no-groups, multi-group, and non-dict cases
  • Updated snapshot results in test/fixtures/results/integration/ and test/fixtures/results/quickstart/ (pure additions of new W4002 entries; no existing entries modified)
  • test/unit/module/cfn_json/test_cfn_json.py — updated expected failure count for vpc-management.json fixture (11 → 27)

Verification:

  • pre-commit run passes (ruff, isort, bandit, mypy, file hygiene)
  • pytest test/unit/ — 2568 passed
  • pytest test/integration/ — 27 passed
  • Smoke-tested end-to-end against a template missing a parameter from ParameterGroups

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

@johnanand707
johnanand707 force-pushed the fix/issue/4115-w4002-parameter-not-in-interface branch 2 times, most recently from 1092c6b to 0c5ccb4 Compare June 9, 2026 00:13
@codecov

codecov Bot commented Jun 11, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 94.43%. Comparing base (43ccef3) to head (420b051).
⚠️ Report is 12 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #4526   +/-   ##
=======================================
  Coverage   94.42%   94.43%           
=======================================
  Files         430      431    +1     
  Lines       15099    15123   +24     
  Branches     2924     2931    +7     
=======================================
+ Hits        14257    14281   +24     
  Misses        461      461           
  Partials      381      381           
Flag Coverage Δ
unittests 94.43% <100.00%> (+<0.01%) ⬆️

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.

@johnanand707
johnanand707 force-pushed the fix/issue/4115-w4002-parameter-not-in-interface branch from 32e344d to 52b1635 Compare June 23, 2026 16:12
Implements the inverse of W4001. While W4001 warns when a parameter
referenced in Metadata AWS::CloudFormation::Interface does not exist
in the Parameters section, W4002 warns when a declared Parameter is
not listed in any ParameterGroup, so it would not appear in the
CloudFormation Console UI.

Closes aws-cloudformation#4115
Adds parametrized cases for malformed Metadata Interface structures:
- ParameterGroups with non-dict entries
- ParameterGroups where Parameters contains non-string entries

Brings patch coverage on InterfaceParameterInGroup.py to 100%.
@johnanand707
johnanand707 force-pushed the fix/issue/4115-w4002-parameter-not-in-interface branch from 52b1635 to 420b051 Compare June 25, 2026 22:11

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

Thanks for the contribution! A few items to address:

1. False positives when ParameterGroups is absent (src/cfnlint/rules/metadata/InterfaceParameterInGroup.py)

The rule fires when AWS::CloudFormation::Interface exists but has no ParameterGroups key. This will produce false positives for templates that only use ParameterLabels — a valid pattern where the user hasn't opted into grouping. If there are no ParameterGroups defined, CloudFormation shows all parameters in a default list anyway, so there's nothing to warn about.

Suggest early-returning when ParameterGroups is absent or empty:

parameter_groups = instance.get("ParameterGroups", [])
if not parameter_groups:
    return

2. Error path should include ParameterGroups (src/cfnlint/rules/metadata/InterfaceParameterInGroup.py)

When ParameterGroups is specified but missing parameters, the error path should include ParameterGroups — that's where the user needs to add the missing entries.

3. Test structure (test/unit/rules/metadata/test_interface_parameter_in_group.py)

The project convention for rule unit tests is to assert against full ValidationError objects (errs == expected), not just counts. See the sibling tests (test_interface_configuration.py, test_interface_parameter_exists.py, test_config.py) — they all construct explicit expected error lists with message, rule, path, etc. This catches regressions in error messages, paths, and rule attribution that a length check would miss.

Additionally, please add a test case for when the template has no parameters defined (empty Parameters section).

return

grouped: set[str] = set()
for group in instance.get("ParameterGroups", []):

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.

The rule fires when AWS::CloudFormation::Interface exists but has no ParameterGroups key. This will produce false positives for templates that only use ParameterLabels. If there are no ParameterGroups defined, CloudFormation shows all parameters in a default list anyway, so there is nothing to warn about.

Suggest early-returning when ParameterGroups is absent or empty:

parameter_groups = instance.get("ParameterGroups", [])
if not parameter_groups:
    return

f"Parameter {param_name!r} is not listed in any "
"Metadata AWS::CloudFormation::Interface ParameterGroup",
rule=self,
)

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.

When ParameterGroups is specified but missing parameters, the error path should include ParameterGroups — that is where the user needs to add the missing entries.

)
for err in errs:
assert isinstance(err, ValidationError)
assert err.rule == rule

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.

The project convention for rule unit tests is to assert against full ValidationError objects (errs == expected), not just counts. See the sibling tests (test_interface_configuration.py, test_interface_parameter_exists.py, test_config.py) — they all construct explicit expected error lists with message, rule, path, etc. This catches regressions in error messages, paths, and rule attribution that a length check would miss.

Additionally, please add a test case for when the template has no parameters defined (empty Parameters section).

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.

W4001 reversed

2 participants