Skip to content

refactor: remove the dead E6004 outputs name rule - #4983

Merged
kddejong merged 1 commit into
aws-cloudformation:mainfrom
kddejong:fix/issue/4877
Nov 2, 2026
Merged

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

Conversation

@kddejong

@kddejong kddejong commented Nov 2, 2026

Copy link
Copy Markdown
Contributor

Fixes #4877. Supersedes #4912, which fixed this by making E6004 fire; this removes it instead.

Problem

E6004 (src/cfnlint/rules/outputs/Pattern.py, "Outputs have appropriate names") has no match and no validate method — it is a docstring and five class attributes. It never fires.

rules/outputs/Configuration.py maps "pattern": "E6004" in its rule_set, but that mapping keys off err.validator, and the Outputs name rule is expressed as patternProperties plus additionalProperties: false in data/schemas/other/outputs/configuration.json. The pattern keyword appears nowhere in that schema, so err.validator == "pattern" can never occur there. A bad output name fails on additionalProperties and is reported by E6001, and --ignore-checks E6004 does nothing.

Measured on upstream/main:

$ cfn-lint -f parseable -t bad_name.yaml
bad_name.yaml:5:3:5:12:E6001:'My_Output' does not match any of the regexes: '^[a-zA-Z0-9]+$'

$ cfn-lint -f parseable -i E6004 -t bad_name.yaml     # no-op
bad_name.yaml:5:3:5:12:E6001:'My_Output' does not match any of the regexes: '^[a-zA-Z0-9]+$'

$ cfn-lint -f parseable -i E6001 -t bad_name.yaml     # silent — the finding really is E6001

Why remove rather than wire it up

The discrimination E6004 implies — separating a bad logical ID from a nested unknown property — exists nowhere else in the codebase. Measured on upstream/main:

Section Bad logical ID Nested unknown property
Resources E3001 E3001
Parameters E2001 E2001
Mappings E7001 —
Outputs E6001 E6001

No section separates the two; each reports its own section rule. Outputs is also the only section whose rule_set maps pattern to a name rule at all — Resources and Mappings have no pattern entry, and Parameters maps pattern to E2003, which is AllowedPattern validation and genuinely fires.

So E6004 assumes a design this codebase does not have. Validation is already correct; only the dead rule is wrong.

Its docstring is also wrong — "Check if Outputs strings are less than the max length" on a rule named "Outputs have appropriate names" — which is further evidence nobody has touched it.

The change

  1. Delete src/cfnlint/rules/outputs/Pattern.py.
  2. Remove "pattern": "E6004" from self.rule_set in src/cfnlint/rules/outputs/Configuration.py. Every other entry is untouched — in particular "propertyNames": "E6011" and "maxLength": "E6011", which carry the working 255-character length check.
  3. docs/rules.md: drop the E6004 row and decrement the headline count 334 → 333 (the generator computes it as len(sorted_rules) + 3, maintenance.py:63; running cfn-lint --update-documentation on this branch produces 333).

No test, snapshot, .cfnlintrc or fixture referenced E6004 — it had no test coverage at all. grep -rn E6004 src/ test/ docs/ scripts/ returns zero hits after the change.

Verification

No user-visible validation changes. Before/after on upstream/main vs this branch, identical in every case:

Check Result (both)
Output named My_Output E6001 ... does not match any of the regexes: '^[a-zA-Z0-9]+$' at 5:3:5:12
Unknown property in an output E6001 Additional properties are not allowed ('Bogus' was unexpected) at 7:5:7:10
Unknown property inside Export E6001, same message, at 12:7:12:12
256-character output name E6011 ... is longer than 255 at 5:3:5:259
Outputs as a list E6003 [{'Value': 'foo'}] is not of type 'object'
Output missing Value E6002 'Value' is a required property
201 outputs E6010 'Outputs' has more than 200 properties
Valid template silent, exit 0

--list-rules no longer lists E6004 and the diff against main is exactly that one rule's two lines (it prints id+shortdesc then description, 662 → 660). -i E6004 now behaves like any unrecognised rule ID: the CLI accepts it silently with no warning or error — confirmed identical to -i E9999999 on main.

Good-fixture sweep, run by hand because test/integration/test_good_templates.py is a curated ~20-template list and does not sweep the directory:

cfn-lint -f parseable -t "test/fixtures/templates/good/**/*.yaml"   # 98 templates, 162 findings
cfn-lint -f parseable -t "test/fixtures/templates/good/**/*.json"   # 9 findings

Noise floor established first by running main against itself three times: byte-identical, 0 differing lines (E3019/E3043, which render Python sets into their messages, do not appear in these fixtures). Against that floor, main vs this branch is byte-identical for both yaml and json, and an order-insensitive check (rule-ID plus file:line multiset) also matches.

Full suite, compared as failure sets rather than counts:

main:   6 failed, 3346 passed, 4 deselected
branch: 6 failed, 3346 passed, 4 deselected

Failure sets are identical. All 6 are pre-existing and caused by missing optional dependencies in the local environment (pydot, junit-xml, sarif), not by this change. The pass count is unchanged at 3346, confirming no test was removed.

pre-commit run --all-files passes (ruff, ruff-format, isort, bandit, mypy, AST/JSON/YAML checks).

Backwards compatibility

A user suppressing E6004 via ignore_checks was suppressing nothing, so the suppression can simply be dropped — it will not start reporting anything new. Users who wanted to suppress the output-name check need E6001, which is where the finding has always come from.

E6004 has no match and no validate method -- it is a docstring and five
class attributes, so it never fires. The Outputs name rule is expressed as
patternProperties plus additionalProperties: false in
data/schemas/other/outputs/configuration.json, so a bad output name fails
on the additionalProperties keyword and is reported by E6001. The pattern
keyword appears nowhere in that schema, so the "pattern": "E6004" entry in
the Outputs configuration rule_set can never be reached and
--ignore-checks E6004 has no effect.

The discrimination E6004 implies exists nowhere else in the codebase. No
section separates a bad logical ID from a nested unknown property -- each
reports its own section rule:

  Resources  bad logical id -> E3001    nested unknown attr -> E3001
  Parameters bad logical id -> E2001    nested unknown prop -> E2001
  Mappings   bad logical id -> E7001
  Outputs    bad logical id -> E6001

Outputs is also the only section whose rule_set maps pattern to a name
rule at all. Resources and Mappings have no pattern entry, and Parameters
maps pattern to E2003, which is AllowedPattern validation and does fire.

Validation is already correct, so this removes the dead rule and leaves
every reported finding unchanged. Users suppressing E6004 can drop the
suppression; it was never doing anything.

Fixes aws-cloudformation#4877
@kddejong
kddejong marked this pull request as ready for review November 2, 2026 23:55
@codecov

codecov Bot commented Nov 2, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 94.73%. Comparing base (588d3c5) to head (4328fc9).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #4983      +/-   ##
==========================================
- Coverage   94.74%   94.73%   -0.01%     
==========================================
  Files         442      441       -1     
  Lines       16145    16138       -7     
  Branches     3138     3138              
==========================================
- Hits        15296    15289       -7     
  Misses        469      469              
  Partials      380      380              
Flag Coverage Δ
unittests 94.73% <ø> (-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.

@kddejong
kddejong merged commit 6f317a9 into aws-cloudformation:main Nov 2, 2026
24 checks passed
@kddejong
kddejong deleted the fix/issue/4877 branch November 2, 2026 23:57
@kddejong kddejong mentioned this pull request Nov 5, 2026
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.

E6004: non-alphanumeric Outputs logical IDs are reported as E6001, so E6004 never fires

1 participant