You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
chore(aws): medium/low findings from the 2026-07-28 full review #53
Reviewed commit: be11bdcb5. Note: origin/main moved to 3e9660d06 during the review; re-verify against current main before changing code, since a finding may have been fixed or moved.
Tracking issue for the MEDIUM and LOW findings from the 2026-07-28 review of providers/aws (all 34 non-test Go files: services/{ec2,rds,elasticache,opensearch,redshift,memorydb,savingsplans}, recommendations/, ladder/, internal/, provider.go, service_client.go). The HIGH findings from the same pass are filed as individual issues; this pass produced no CRITICAL.
Context: this module is not covered by CI (LeanerCloud/cloud-commitments-cli#1478), so nothing in this checklist has been vetted by go vet, golangci-lint, or the unit/integration suites.
Each checklist item is independently actionable. Please keep the file:line, failure scenario and fix direction with the item when splitting any of these out.
Savings Plan commitment is rounded to 2 decimals before purchase, changing the approved dollar amount (MEDIUM)
Where: providers/aws/services/savingsplans/client.go:232 (Commitment: aws.String(fmt.Sprintf("%.2f", spDetails.HourlyCommitment))); the pre-rounding positivity guard is at providers/aws/ladder/purchase.go:141-143
What: Cost Explorer returns HourlyCommitmentToPurchase at full precision and the AWS Savings Plans API accepts sub-cent commitments. %.2f both rounds and can floor to zero. The ladder validates HourlyCommitment > 0, but that guard runs on the pre-rounding value, so a positive commitment can still be sent as "0.00".
Failure scenario: a ladder ramp step or a small account produces HourlyCommitment = 0.0142/hr. CUDly buys 0.01/hr, a 30% under-commit against the approved plan, silently, for the whole 1 to 3 year term. At HourlyCommitment = 0.004 the request carries "0.00": either AWS rejects it (an opaque failure on an already-approved purchase) or a zero-value commitment is created. Rounding the other way (0.0151 -> 0.02) over-commits real money beyond what was approved.
Fix: format with the precision the API accepts (%.3f, or strconv.FormatFloat(v, 'f', -1, 64)) and reject a commitment that would not round-trip, rather than silently re-pricing the approved amount.
ElastiCache offering lookup passes an unvalidated (possibly empty) engine and accepts the first offering on the page (MEDIUM)
Where: providers/aws/services/elasticache/client.go:309-316 (ProductDescription: aws.String(details.Engine)) and :346-357 (scanElastiCacheOfferingPage returns the first entry after checking only OfferingType); the producing parser sets Engine only when CE supplies it, providers/aws/recommendations/parser_services.go:69-71
What: CacheDetails.Engine is copied verbatim from CE's ProductDescription with no validation and no non-empty guard. This is the one remaining service without the guard its siblings have: RDS refuses an empty AZConfig and ambiguous engines (rds/client.go:314-322, :573-619), and MemoryDB refuses a missing NodeType (parser_services.go:247-249). The page scanner then validates only the payment option, not node type, duration, or engine, so whatever AWS returns first for the remaining filter set is purchased.
Failure scenario: CE omits ProductDescription (nil pointer) for an ElastiCache recommendation, so cacheInfo.Engine stays "" and the request carries an empty ProductDescription filter. Redis and Memcached reserved nodes for the same node type, term and payment option are priced differently and cover different clusters. If AWS treats the empty value as "unfiltered", the first returned offering is bought and the customer holds a reservation for the wrong engine. If AWS instead treats it as "match nothing", the purchase fails with the misleading "no offerings found" rather than naming the missing field.
Fix: reject an empty details.Engine in findOfferingID with an explicit error (same shape as the RDS AZConfig guard), and have scanElastiCacheOfferingPage verify CacheNodeType, Duration and ProductDescription on the chosen offering before returning it. Note that LeanerCloud/cloud-commitments-cli#1052's 08-H3 covered the ElastiCache payment-option default, which is already fixed at :462-475; the engine and the first-match-wins scan are not covered by it.
The CE-supplied Savings Plans offering ID short-circuits the scoped-client plan-type guard (MEDIUM)
Where: providers/aws/services/savingsplans/client.go:425-428 in findOfferingID: the spDetails.OfferingID != "" early return happens beforeresolveSPPlanType (:430), convertTermToSeconds (:434) and convertPaymentOption (:438)
What: resolveSPPlanType exists specifically to "reject mismatches to prevent buying the wrong product" (:275), and the term and payment converters are the fail-loud validation for those two fields. All three are skipped whenever the recommendation carries an offering ID, which is the normal case for EC2Instance SPs (providers/aws/recommendations/parser_sp.go:259). Nothing downstream re-checks: CreateSavingsPlan is called with the offering ID and the commitment only (:230-236).
Failure scenario: a persisted recommendation row tagged savings-plans-compute (so provider.go:472-477 builds a Compute-scoped client) but whose JSONB Details carry plan_type: "EC2Instance" and an EC2Instance offering_id. That is exactly the shape produced by pre-split umbrella rows, which provider.go:478-488 exists to handle because such rows do persist. The scope guard that would have refused the purchase never runs, and a region-locked and family-locked EC2Instance SP is bought under a Compute SP plan and approval. Similarly, a row whose Term or PaymentOption are unparseable buys whatever the offering ID encodes instead of failing loud.
Fix: run resolveSPPlanType, convertTermToSeconds and convertPaymentOption before the offering-ID short-circuit so the fast path is validated identically to the lookup path.
The RI recommendation fetch uses the deprecated silent converters, so a bad term or payment silently gets Cost Explorer's defaults under the requested label (MEDIUM)
Where: providers/aws/recommendations/client.go:149-155 calls convertPaymentOption, convertTermInYears and convertLookbackPeriod, the three functions explicitly marked Deprecated: ... silently returns the empty ("") at providers/aws/recommendations/converters.go:32-42, :74-84, :102-112; the parser then labels every returned rec with the requested strings at parser_ri.go:40-47 (PaymentOption: params.PaymentOption, Term: params.Term)
What: an unrecognised value yields the zero-value enum, which the SDK omits from the request. Cost Explorer then applies its own server-side defaults for TermInYears, PaymentOption and LookbackPeriodInDays rather than erroring. The recommendation is stored and displayed with the caller's string while its savings figures describe a different commitment.
Failure scenario: the scheduler's fallback path builds Term: fmt.Sprintf("%dyr", globalCfg.DefaultTerm) and PaymentOption: globalCfg.DefaultPayment (internal/scheduler/scheduler.go:894-898). With DefaultTerm unset this is "0yr", and with DefaultPayment unset it is "". Both convert to "", CE returns its default-term and default-payment recommendations, and the rows land in the DB labelled term=0yr, payment= with savings that belong to a different commitment shape. The operator sees a savings number that will never be realised, and the purchase later fails at getDurationValue("0yr") (ec2/client.go:672-681) with no link back to the mislabelled rec.
No purchase path reconciles the resolved offering's price against the approved recommendation cost, and EC2's LimitPrice cap is unused (MEDIUM)
Where: providers/aws/services/ec2/client.go:151-155 (PurchaseReservedInstancesOfferingInput built with only ReservedInstancesOfferingId and InstanceCount; the SDK's LimitPrice *types.ReservedInstanceLimitPrice field is available and never set), and the equivalent inputs at rds/client.go:162-167, elasticache/client.go:163-168, memorydb/client.go:159-164, opensearch/client.go:202-206, redshift/client.go:189-192
What: offering selection is "first match on the filtered page", and the offering's FixedPrice / UsagePrice are never compared against rec.CommitmentCost (the CE-parsed upfront, parser_ri.go:167-173) before committing. EC2 is the one AWS RI API that offers a server-enforced ceiling on the total charge, and it is left nil.
Failure scenario: a recommendation is collected with UpfrontCost = $12,000 and approved under a MaxPurchaseAmount constraint evaluated on that stored figure. By execution time (recommendations are cached and plans can be scheduled days later) AWS has repriced the offering, or the filter set matched a differently-priced variant. The purchase proceeds at the real price with no ceiling and no post-hoc comparison, so the approved cap is bypassed and nothing in the result signals the divergence. result.Cost is not even populated for EC2, which is the separately filed HIGH from this pass, so the divergence is not even recorded after the fact.
Fix: fetch the resolved offering's price during findOfferingID, refuse (or require re-approval) when it exceeds the recommendation's cost by more than a configured tolerance, and set LimitPrice on the EC2 purchase as server-side defence in depth.
CE utilization is keyed by SUBSCRIPTION_ID and joined against ReservedInstancesId; if the two vocabularies differ, RI reshape silently never fires (MEDIUM, verification gap)
Where: providers/aws/recommendations/utilization.go:57-62 (GroupBy: SUBSCRIPTION_ID) then :162 (id := aws.ToString(detail.Key)) into RIUtilization.ReservedInstanceID. Consumers join on that string: providers/aws/ladder/layer_states.go:337-350 (utilsForConvertibleRIs intersects against ec2svc.ConvertibleRI.ReservedInstanceID, sourced from DescribeReservedInstances.ReservedInstancesId at ec2/client.go:743) and internal/api/handler_ri_exchange.go:495 into pkg/exchange/reshape.go:418,445 (utilMap[u.RIID], then util, ok := utilMap[ri.ID])
What: the join assumes CE's SUBSCRIPTION_ID group key is byte-identical to the EC2 ReservedInstancesId UUID. That equivalence is not established anywhere in the code, and both consumers fail silently if it does not hold: analyzeRI returns nil on a lookup miss (reshape.go:445-448) and computeRIUtilizationPct returns nil when the filtered slice is empty (layer_states.go:358-367).
Failure scenario: if CE returns a subscription identifier rather than the RI UUID, utilsForConvertibleRIs filters every entry out, the ladder's UtilizationPct is permanently nil ("unmeasured"), reshape triggering is disabled, and AnalyzeReshaping returns zero recommendations for an account full of 20%-utilised convertible RIs. The feature appears to work (no errors, empty result) while producing nothing.
Fix: verify the key vocabulary once against a live account and, either way, log or count the join miss rate so a total mismatch surfaces as a warning instead of an empty result set. Distinct from LeanerCloud/cloud-commitments-cli#1482, which is about pool-key blending in the coverage path.
normalizeRegionName misses the modern "Europe (...)" display names Cost Explorer uses (LOW)
Where: providers/aws/recommendations/converters.go:137-166 (the alias map) and :173-178 (the trailing prefix checks)
What: the map carries the retired EU (Ireland) / EU (Frankfurt) / EU (London) / EU (Paris) / EU (Stockholm) spellings, but the current Europe (...) spellings only for Milan, Spain and Zurich. The trailing prefix checks are dead code: both branches return region unchanged.
Failure scenario: if CE returns Europe (Ireland) for an RDS, EC2 or ElastiCache recommendation, rec.Region becomes the literal display string. Coverage lookups key on region:instance_type (coverage.go:84-86) and will never match the eu-west-1-keyed coverage entry, so ExistingCoveragePct stays 0 and sizing over-buys. Region filters and per-region client construction (provider.go:456-457) also misbehave.
Fix: add the Europe (...) aliases (and the newer ap-southeast-5 / ap-southeast-7, ca-west-1, mx-central-1 regions), and drop the dead prefix branch.
resolveAccountID memoises a transient STS failure for the client's lifetime, permanently disabling Redshift's idempotency guard (LOW)
Where: providers/aws/services/redshift/client.go:307-322 and providers/aws/services/opensearch/client.go:312-327 (c.accountOnce.Do stores c.accountErr)
What: a single failed GetCallerIdentity (throttle, transient network error, or a context deadline on the first call) is cached, and every later call returns the same error without retrying. On Redshift that error is fatal to the pre-purchase tag guard, which fails loud by design (:174-186).
Failure scenario: one throttled STS call at the start of a purchase run makes every subsequent Redshift purchase in that run return "idempotency lookup failed ... refusing to purchase", and post-purchase tagging is disabled for the client, so a later re-drive cannot recognise already-purchased nodes.
Fix: cache only successful lookups and retry on error.
Savings Plans commitment dates are silently dropped when unparseable (LOW)
Where: providers/aws/services/savingsplans/client.go:195-204 (toCommitment ignores the time.Parse error, leaving StartDate and EndDate at the zero time)
What: the ladder's own SP mapper fails loud on the same fields for exactly this reason. Its comment at providers/aws/ladder/adapters.go:195-205 says a silently zero EndDate "would drop the SP from sumExpiringSPHourlyCost and understate expiring commitment". The provider-level GetExistingCommitments has the inconsistent, silent behaviour.
Failure scenario: an SP with a malformed End string yields EndDate = zero, which expiringCountsByPool (providers/aws/recommendations/expiry.go:52) and sumExpiringSPHourlyCost both skip as "no expiry known". The expiring commitment is never replaced, so the account silently drops to on-demand when the SP lapses.
Fix: return an error (or at minimum log) instead of discarding the parse failure, matching parseSPDate.
GetRICoverageMap silently substitutes a 30-day window for a non-positive lookbackDays (LOW)
Where: providers/aws/recommendations/coverage.go:179-181; the same pattern at providers/aws/recommendations/utilization.go:45-47
What: a caller misconfiguration (lookbackDays = 0) is absorbed into a hardcoded 30, while the sibling Savings Plans paths reject it explicitly (sp_coverage.go:305-307, :420-422).
Failure scenario: an unset lookback config silently sizes purchases from a 30-day window the operator never chose, with no signal that the configured value was ignored.
Fix: return an error, matching GetSPCoverageSummary.
What: MemoryDB now supports Valkey as well as Redis, and the parser stamps redis unconditionally. The MemoryDB purchase path does not use Engine today (memorydb/client.go:313-319 filters only on NodeType, OfferingType and Duration), so the impact is confined to display, pool keying and duplicate detection.
Failure scenario: a Valkey MemoryDB cluster's recommendation is labelled redis in the UI and in any engine-keyed comparison, so two clusters on different engines collapse into one pool key.
Fix: read the engine from MemoryDBInstanceDetails if CE exposes it; otherwise leave it empty rather than asserting a wrong value.
Verified duplicates: checked against the open backlog and deliberately not re-reported
Each of these was independently confirmed against the cited issue's body, not just its title.
RateLimiter.Wait skips ctx.Err() on the first attempt (ratelimiter.go:69-72) -> LeanerCloud/cloud-commitments-cli#1303, which quotes the exact retryCount == 0 early return.
parseFloat silently returns 0 for RI utilization hours (utilization.go:180-195) -> LeanerCloud/cloud-commitments-cli#1308, which names PurchasedHours / TotalActualHours / UnusedHours explicitly.
computeEC2CoveragePct blending non-EC2 pool keys (ladder/layer_states.go:295-329) -> LeanerCloud/cloud-commitments-cli#1482.
Partial per-service failure returns success with that service's recs dropped (recommendations/client.go:453-476) -> LeanerCloud/cloud-commitments-cli#1052, finding 08-H4.
USD-only SP, ElastiCache and MemoryDB currency assumptions (savingsplans/client.go:303,635) -> LeanerCloud/cloud-commitments-cli#1087, which cites the same USD hardcodes plus memorydb/client.go:425 and elasticache/client.go:394.
Untyped all-services-failed error -> LeanerCloud/cloud-commitments-cli#1316. Duplicated RI-term parsers and CE pagination helpers -> LeanerCloud/cloud-commitments-cli#1392, LeanerCloud/cloud-commitments-cli#1393. Copy-pasted purchase skeleton across the RI service clients -> LeanerCloud/cloud-commitments-cli#1191.
Added by an automated audit of 3c0f8ac94048a2c36fce5ccddee54e6c4849a5cd (tip of origin/main). Each item below was reported by one reviewer and independently confirmed by a second that did not write it. Full report: docs/audits/codebase-audit-2026-09-02.md.
A07-033 (medium)
For the verification bar on these two bullets: the current suite cannot fail on either. Every CacheDetails literal in providers/aws/services/elasticache/client_test.go uses the already-lowercase "redis" (:251, :288, :341, :446, :560, :616, :647, :680, :714, :737, :762), with no title-cased and no empty-engine case, so the raw Cost Explorer ProductDescription reaching the offering filter is never exercised. On the Savings Plans side, the only test with a non-empty OfferingID is TestEC2InstanceSP_CEProvidedOfferingIDUsedDirectly (savingsplans/client_test.go:1512-1537), and it asserts only that the offerings API is skipped -- nothing asserts that a plan-type, term or payment-option mismatch is still rejected on that path; the plan-type rejection test at :364-385 uses a rec with no OfferingID, so it never reaches the short-circuit. Both fixes need a case that fails against current code first. (audit finding A07-033)
A09-009 (medium)
A second silent path in the same file as the utilization join-key finding. AnalyzeReshapingWithRecs (pkg/exchange/reshape.go:550-555) collapses err != nil and len(offerings) == 0 into one branch that returns recs, and err is never logged or wrapped anywhere in the function. A database outage or a permission regression in the PurchaseRecLookup closure therefore renders the reshape page with zero cross-family alternatives on every request, indistinguishable from 'AWS has not recommended anything for this region'. Splitting the branches and emitting a warning on the error arm is enough to make a persistent failure visible. Audit finding A09-009.
Reviewed commit:
be11bdcb5. Note:origin/mainmoved to3e9660d06during the review; re-verify against currentmainbefore changing code, since a finding may have been fixed or moved.Tracking issue for the MEDIUM and LOW findings from the 2026-07-28 review of
providers/aws(all 34 non-test Go files:services/{ec2,rds,elasticache,opensearch,redshift,memorydb,savingsplans},recommendations/,ladder/,internal/,provider.go,service_client.go). The HIGH findings from the same pass are filed as individual issues; this pass produced no CRITICAL.Context: this module is not covered by CI (LeanerCloud/cloud-commitments-cli#1478), so nothing in this checklist has been vetted by
go vet, golangci-lint, or the unit/integration suites.Each checklist item is independently actionable. Please keep the file:line, failure scenario and fix direction with the item when splitting any of these out.
Savings Plan commitment is rounded to 2 decimals before purchase, changing the approved dollar amount (MEDIUM)
providers/aws/services/savingsplans/client.go:232(Commitment: aws.String(fmt.Sprintf("%.2f", spDetails.HourlyCommitment))); the pre-rounding positivity guard is atproviders/aws/ladder/purchase.go:141-143HourlyCommitmentToPurchaseat full precision and the AWS Savings Plans API accepts sub-cent commitments.%.2fboth rounds and can floor to zero. The ladder validatesHourlyCommitment > 0, but that guard runs on the pre-rounding value, so a positive commitment can still be sent as"0.00".HourlyCommitment = 0.0142/hr. CUDly buys0.01/hr, a 30% under-commit against the approved plan, silently, for the whole 1 to 3 year term. AtHourlyCommitment = 0.004the request carries"0.00": either AWS rejects it (an opaque failure on an already-approved purchase) or a zero-value commitment is created. Rounding the other way (0.0151 -> 0.02) over-commits real money beyond what was approved.%.3f, orstrconv.FormatFloat(v, 'f', -1, 64)) and reject a commitment that would not round-trip, rather than silently re-pricing the approved amount.ElastiCache offering lookup passes an unvalidated (possibly empty) engine and accepts the first offering on the page (MEDIUM)
providers/aws/services/elasticache/client.go:309-316(ProductDescription: aws.String(details.Engine)) and:346-357(scanElastiCacheOfferingPagereturns the first entry after checking onlyOfferingType); the producing parser setsEngineonly when CE supplies it,providers/aws/recommendations/parser_services.go:69-71CacheDetails.Engineis copied verbatim from CE'sProductDescriptionwith no validation and no non-empty guard. This is the one remaining service without the guard its siblings have: RDS refuses an emptyAZConfigand ambiguous engines (rds/client.go:314-322,:573-619), and MemoryDB refuses a missing NodeType (parser_services.go:247-249). The page scanner then validates only the payment option, not node type, duration, or engine, so whatever AWS returns first for the remaining filter set is purchased.ProductDescription(nil pointer) for an ElastiCache recommendation, socacheInfo.Enginestays""and the request carries an emptyProductDescriptionfilter. Redis and Memcached reserved nodes for the same node type, term and payment option are priced differently and cover different clusters. If AWS treats the empty value as "unfiltered", the first returned offering is bought and the customer holds a reservation for the wrong engine. If AWS instead treats it as "match nothing", the purchase fails with the misleading "no offerings found" rather than naming the missing field.details.EngineinfindOfferingIDwith an explicit error (same shape as the RDSAZConfigguard), and havescanElastiCacheOfferingPageverifyCacheNodeType,DurationandProductDescriptionon the chosen offering before returning it. Note that LeanerCloud/cloud-commitments-cli#1052's 08-H3 covered the ElastiCache payment-option default, which is already fixed at:462-475; the engine and the first-match-wins scan are not covered by it.The CE-supplied Savings Plans offering ID short-circuits the scoped-client plan-type guard (MEDIUM)
providers/aws/services/savingsplans/client.go:425-428infindOfferingID: thespDetails.OfferingID != ""early return happens beforeresolveSPPlanType(:430),convertTermToSeconds(:434) andconvertPaymentOption(:438)resolveSPPlanTypeexists specifically to "reject mismatches to prevent buying the wrong product" (:275), and the term and payment converters are the fail-loud validation for those two fields. All three are skipped whenever the recommendation carries an offering ID, which is the normal case for EC2Instance SPs (providers/aws/recommendations/parser_sp.go:259). Nothing downstream re-checks:CreateSavingsPlanis called with the offering ID and the commitment only (:230-236).savings-plans-compute(soprovider.go:472-477builds a Compute-scoped client) but whose JSONBDetailscarryplan_type: "EC2Instance"and an EC2Instanceoffering_id. That is exactly the shape produced by pre-split umbrella rows, whichprovider.go:478-488exists to handle because such rows do persist. The scope guard that would have refused the purchase never runs, and a region-locked and family-locked EC2Instance SP is bought under a Compute SP plan and approval. Similarly, a row whoseTermorPaymentOptionare unparseable buys whatever the offering ID encodes instead of failing loud.resolveSPPlanType,convertTermToSecondsandconvertPaymentOptionbefore the offering-ID short-circuit so the fast path is validated identically to the lookup path.The RI recommendation fetch uses the deprecated silent converters, so a bad term or payment silently gets Cost Explorer's defaults under the requested label (MEDIUM)
providers/aws/recommendations/client.go:149-155callsconvertPaymentOption,convertTermInYearsandconvertLookbackPeriod, the three functions explicitly markedDeprecated: ... silently returns the empty ("")atproviders/aws/recommendations/converters.go:32-42,:74-84,:102-112; the parser then labels every returned rec with the requested strings atparser_ri.go:40-47(PaymentOption: params.PaymentOption, Term: params.Term)TermInYears,PaymentOptionandLookbackPeriodInDaysrather than erroring. The recommendation is stored and displayed with the caller's string while its savings figures describe a different commitment.Term: fmt.Sprintf("%dyr", globalCfg.DefaultTerm)andPaymentOption: globalCfg.DefaultPayment(internal/scheduler/scheduler.go:894-898). WithDefaultTermunset this is"0yr", and withDefaultPaymentunset it is"". Both convert to"", CE returns its default-term and default-payment recommendations, and the rows land in the DB labelledterm=0yr, payment=with savings that belong to a different commitment shape. The operator sees a savings number that will never be realised, and the purchase later fails atgetDurationValue("0yr")(ec2/client.go:672-681) with no link back to the mislabelled rec.GetRecommendationstoconvertPaymentOptionE/convertTermInYearsE/convertLookbackPeriodEand propagate the error; delete the deprecated wrappers once the last caller is gone. The deprecation note points at fix(aws/recommendations): protect RateLimiter against concurrent access (closes #271) cloud-commitments-cli#865 and fix(aws): payment-option/engine/term correctness gaps in AWS RI service clients cloud-commitments-cli#1075, both closed; no open issue covers the remaining caller.No purchase path reconciles the resolved offering's price against the approved recommendation cost, and EC2's
LimitPricecap is unused (MEDIUM)providers/aws/services/ec2/client.go:151-155(PurchaseReservedInstancesOfferingInputbuilt with onlyReservedInstancesOfferingIdandInstanceCount; the SDK'sLimitPrice *types.ReservedInstanceLimitPricefield is available and never set), and the equivalent inputs atrds/client.go:162-167,elasticache/client.go:163-168,memorydb/client.go:159-164,opensearch/client.go:202-206,redshift/client.go:189-192FixedPrice/UsagePriceare never compared againstrec.CommitmentCost(the CE-parsed upfront,parser_ri.go:167-173) before committing. EC2 is the one AWS RI API that offers a server-enforced ceiling on the total charge, and it is left nil.UpfrontCost = $12,000and approved under aMaxPurchaseAmountconstraint evaluated on that stored figure. By execution time (recommendations are cached and plans can be scheduled days later) AWS has repriced the offering, or the filter set matched a differently-priced variant. The purchase proceeds at the real price with no ceiling and no post-hoc comparison, so the approved cap is bypassed and nothing in the result signals the divergence.result.Costis not even populated for EC2, which is the separately filed HIGH from this pass, so the divergence is not even recorded after the fact.findOfferingID, refuse (or require re-approval) when it exceeds the recommendation's cost by more than a configured tolerance, and setLimitPriceon the EC2 purchase as server-side defence in depth.CE utilization is keyed by
SUBSCRIPTION_IDand joined againstReservedInstancesId; if the two vocabularies differ, RI reshape silently never fires (MEDIUM, verification gap)providers/aws/recommendations/utilization.go:57-62(GroupBy: SUBSCRIPTION_ID) then:162(id := aws.ToString(detail.Key)) intoRIUtilization.ReservedInstanceID. Consumers join on that string:providers/aws/ladder/layer_states.go:337-350(utilsForConvertibleRIsintersects againstec2svc.ConvertibleRI.ReservedInstanceID, sourced fromDescribeReservedInstances.ReservedInstancesIdatec2/client.go:743) andinternal/api/handler_ri_exchange.go:495intopkg/exchange/reshape.go:418,445(utilMap[u.RIID], thenutil, ok := utilMap[ri.ID])SUBSCRIPTION_IDgroup key is byte-identical to the EC2ReservedInstancesIdUUID. That equivalence is not established anywhere in the code, and both consumers fail silently if it does not hold:analyzeRIreturns nil on a lookup miss (reshape.go:445-448) andcomputeRIUtilizationPctreturns nil when the filtered slice is empty (layer_states.go:358-367).utilsForConvertibleRIsfilters every entry out, the ladder'sUtilizationPctis permanently nil ("unmeasured"), reshape triggering is disabled, andAnalyzeReshapingreturns zero recommendations for an account full of 20%-utilised convertible RIs. The feature appears to work (no errors, empty result) while producing nothing.normalizeRegionNamemisses the modern "Europe (...)" display names Cost Explorer uses (LOW)providers/aws/recommendations/converters.go:137-166(the alias map) and:173-178(the trailing prefix checks)EU (Ireland)/EU (Frankfurt)/EU (London)/EU (Paris)/EU (Stockholm)spellings, but the currentEurope (...)spellings only for Milan, Spain and Zurich. The trailing prefix checks are dead code: both branchesreturn regionunchanged.Europe (Ireland)for an RDS, EC2 or ElastiCache recommendation,rec.Regionbecomes the literal display string. Coverage lookups key onregion:instance_type(coverage.go:84-86) and will never match theeu-west-1-keyed coverage entry, soExistingCoveragePctstays 0 and sizing over-buys. Region filters and per-region client construction (provider.go:456-457) also misbehave.Europe (...)aliases (and the newerap-southeast-5/ap-southeast-7,ca-west-1,mx-central-1regions), and drop the dead prefix branch.resolveAccountIDmemoises a transient STS failure for the client's lifetime, permanently disabling Redshift's idempotency guard (LOW)providers/aws/services/redshift/client.go:307-322andproviders/aws/services/opensearch/client.go:312-327(c.accountOnce.Dostoresc.accountErr)GetCallerIdentity(throttle, transient network error, or a context deadline on the first call) is cached, and every later call returns the same error without retrying. On Redshift that error is fatal to the pre-purchase tag guard, which fails loud by design (:174-186).Savings Plans commitment dates are silently dropped when unparseable (LOW)
providers/aws/services/savingsplans/client.go:195-204(toCommitmentignores thetime.Parseerror, leavingStartDateandEndDateat the zero time)providers/aws/ladder/adapters.go:195-205says a silently zeroEndDate"would drop the SP fromsumExpiringSPHourlyCostand understate expiring commitment". The provider-levelGetExistingCommitmentshas the inconsistent, silent behaviour.Endstring yieldsEndDate = zero, whichexpiringCountsByPool(providers/aws/recommendations/expiry.go:52) andsumExpiringSPHourlyCostboth skip as "no expiry known". The expiring commitment is never replaced, so the account silently drops to on-demand when the SP lapses.parseSPDate.GetRICoverageMapsilently substitutes a 30-day window for a non-positivelookbackDays(LOW)providers/aws/recommendations/coverage.go:179-181; the same pattern atproviders/aws/recommendations/utilization.go:45-47lookbackDays = 0) is absorbed into a hardcoded 30, while the sibling Savings Plans paths reject it explicitly (sp_coverage.go:305-307,:420-422).GetSPCoverageSummary.MemoryDB recommendations hardcode
Engine: "redis"(LOW)providers/aws/recommendations/parser_services.go:255-258redisunconditionally. The MemoryDB purchase path does not useEnginetoday (memorydb/client.go:313-319filters only on NodeType, OfferingType and Duration), so the impact is confined to display, pool keying and duplicate detection.redisin the UI and in any engine-keyed comparison, so two clusters on different engines collapse into one pool key.MemoryDBInstanceDetailsif CE exposes it; otherwise leave it empty rather than asserting a wrong value.Verified duplicates: checked against the open backlog and deliberately not re-reported
Each of these was independently confirmed against the cited issue's body, not just its title.
ec2/client.go:409-416,savingsplans/client.go:655-682:calculateHoursInTerm,normalizeTermString,calculatePaymentBreakdown's default branch) -> LeanerCloud/cloud-commitments-cli#1319 (EC2getDurationValueplus tenancy), LeanerCloud/cloud-commitments-cli#1320 (the two SP helpers, quoted verbatim in that issue), fix(providers/aws): getDurationString/getDurationValue silently fallback to 1yr on unrecognized term cloud-commitments-cli#1266, LeanerCloud/cloud-commitments-cli#1383, fix(providers/aws): fail loud on unrecognized RI term in EC2 getDurationValue cloud-commitments-cli#1260, and the umbrella LeanerCloud/cloud-commitments-cli#1194.RateLimiter.Waitskipsctx.Err()on the first attempt (ratelimiter.go:69-72) -> LeanerCloud/cloud-commitments-cli#1303, which quotes the exactretryCount == 0early return.parseFloatsilently returns 0 for RI utilization hours (utilization.go:180-195) -> LeanerCloud/cloud-commitments-cli#1308, which namesPurchasedHours/TotalActualHours/UnusedHoursexplicitly.computeEC2CoveragePctblending non-EC2 pool keys (ladder/layer_states.go:295-329) -> LeanerCloud/cloud-commitments-cli#1482.recommendations/client.go:453-476) -> LeanerCloud/cloud-commitments-cli#1052, finding 08-H4.savingsplans/client.go:303,635) -> LeanerCloud/cloud-commitments-cli#1087, which cites the same USD hardcodes plusmemorydb/client.go:425andelasticache/client.go:394.Findings from the 2026-09-02 codebase audit
Added by an automated audit of
3c0f8ac94048a2c36fce5ccddee54e6c4849a5cd(tip oforigin/main). Each item below was reported by one reviewer and independently confirmed by a second that did not write it. Full report:docs/audits/codebase-audit-2026-09-02.md.A07-033 (medium)
For the verification bar on these two bullets: the current suite cannot fail on either. Every
CacheDetailsliteral inproviders/aws/services/elasticache/client_test.gouses the already-lowercase"redis"(:251, :288, :341, :446, :560, :616, :647, :680, :714, :737, :762), with no title-cased and no empty-engine case, so the raw Cost ExplorerProductDescriptionreaching the offering filter is never exercised. On the Savings Plans side, the only test with a non-emptyOfferingIDisTestEC2InstanceSP_CEProvidedOfferingIDUsedDirectly(savingsplans/client_test.go:1512-1537), and it asserts only that the offerings API is skipped -- nothing asserts that a plan-type, term or payment-option mismatch is still rejected on that path; the plan-type rejection test at :364-385 uses a rec with noOfferingID, so it never reaches the short-circuit. Both fixes need a case that fails against current code first. (audit finding A07-033)A09-009 (medium)
A second silent path in the same file as the utilization join-key finding. AnalyzeReshapingWithRecs (pkg/exchange/reshape.go:550-555) collapses
err != nilandlen(offerings) == 0into one branch that returns recs, and err is never logged or wrapped anywhere in the function. A database outage or a permission regression in the PurchaseRecLookup closure therefore renders the reshape page with zero cross-family alternatives on every request, indistinguishable from 'AWS has not recommended anything for this region'. Splitting the branches and emitting a warning on the error arm is enough to make a persistent failure visible. Audit finding A09-009.