Repository navigation
fix: handle unscheduled Lambda runtime block dates - #4945
Merged
Merged
Conversation
E2531, E2533 and W2531 called datetime.strptime on create-block and update-block without a null guard, so a runtime whose deprecation date is announced before its block dates are scheduled raised instead of being validated. A null block date now means 'not yet scheduled': W2531 fires on the deprecation date alone, and E2531 and E2533 stay silent until their own block date is both scheduled and reached. Fixes aws-cloudformation#4944
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #4945 +/- ##
=======================================
Coverage 94.68% 94.69%
=======================================
Files 441 442 +1
Lines 16058 16083 +25
Branches 3114 3119 +5
=======================================
+ Hits 15204 15229 +25
Misses 470 470
Partials 384 384
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #4944
Problem
LmbdRuntimeLifecycle.jsonpermitscreate-blockandupdate-blockto benull, which is how AWS publishes a runtime whose deprecation date is announced but whose block dates are not yet scheduled. All three rules that read the file calleddatetime.strptimeon those values with no null guard, so such a runtime raised instead of being validated.dotnet9is the only entry in that state today ({"create-block": null, "deprecated": "2026-11-10", "successor": "dotnet10", "update-block": null}), matching the Lambda runtimes page, which shows "Not scheduled" for both block columns. The data is correct — AWS announces the deprecation date first and the block dates later, so every runtime passes through this state.Reproduced on
mainat027bdd1b9:E2531andE2533raise today.W2531survives only becauseandshort-circuits on the deprecation comparison, which is still false. With the clock frozen the way the rules' own tests do it:So W2531 joins the other two on 2026-11-10.
Fix
A null block date now means "not yet scheduled" rather than being parsed as a date. Each date is handled independently, since AWS can schedule one before the other.
deprecated <= today and create-block > today and update-block > todaycreate-block <= today and update-block > todaycreate-blockis null; a nullupdate-blocksatisfies the second clause (creates blocked, updates not)update-block <= todayupdate-blockis nullE2531 and E2533 staying silent is deliberate: CloudFormation is not refusing the operation yet, so an error would be a false positive. W2531 firing is the finding users want in that state — the runtime is deprecated even though AWS has not said when creates get blocked.
Message
The shared message interpolated both block dates, which rendered as
Creation was disabled on None and update on None. The three rules now build it through one helper that varies only the middle clause:Creation was disabled on 'C' and update on 'U'.(unchanged, byte-identical)Creation was disabled on 'C' and update blocking is not yet scheduled.Creation blocking is not yet scheduled and update was disabled on 'U'.Creation and update blocking are not yet scheduled.The both-scheduled string is byte-identical to the old one on purpose, because four quickstart snapshot fixtures and the existing unit tests assert it. No snapshot needed regenerating.
Frozen-clock output after the fix:
Verification
cfn-lint -ton the issue's template: no E1101. (dotnet9still drawsE3030because it is absent from theRuntimeenum — a schema gap belonging in resource-provider-enhanced-schemas, noted in the issue.)main). Every single difference is ondotnet9; no other runtime changed its result in any way.main:cfn-lint -t "test/fixtures/templates/good/**/*.yaml", diffed against the same command run from a pristineupstream/mainworktree.git status test/fixtures/results/is clean.9 failed, 3235 passed, the identical 9 failures by test ID as a pristineupstream/mainrun of the same suite in the same checkout (9 failed, 3220 passed). All 9 are missing optional dependencies (pydot, junit, sarif) and the pricing-API tests. The +15 are the new cases.pre-commit run --all-files: ruff, ruff-format, isort, bandit and mypy all pass.Tests
Five cases per rule, covering a null-block entry before and after its deprecation date and both half-scheduled permutations. They use an injected synthetic entry rather than the real
dotnet9row, so they keep testing the code path after AWS schedulesdotnet9's block dates and the data file is updated.11 of the 15 new cases fail against pre-fix code with the reported
TypeError; the other 4 pass there only because short-circuiting never reaches the null.Not included
nodejs26.xandpython3.15are currently omitted fromLmbdRuntimeLifecycle.jsonto dodge this crash. With it fixed they could be carried, and unlikedotnet9both are in theRuntimeenum — so adding them would change live behaviour for real templates. That is a data decision, left to the maintainer.LmbdRuntimeLifecycle.jsonis untouched here.