Skip to content

chore: Omit analyticsSpecs without instanceSize in INFINITE PATCH payloads - #4747

Draft
lantoli wants to merge 6 commits into
CLOUDP-427153_dev_infinitefrom
CLOUDP-447210_fix_patch
Draft

lantoli wants to merge 6 commits into
CLOUDP-427153_dev_infinitefrom
CLOUDP-447210_fix_patch

Conversation

@lantoli

@lantoli lantoli commented Sep 18, 2026

Copy link
Copy Markdown
Member

Description

When clearing storage_config on an INFINITE cluster, the forced replicationSpecs PATCH included analyticsSpecs with nodeCount=0 but no instanceSize, causing Atlas to return 400 MISSING_ATTRIBUTE. Atlas was returning 500 instead of 400, which made this provider bug look like an Atlas issue until the 500 was fixed.

Root Cause

The issue was in the Terraform provider, not Atlas. The bug only triggers for INFINITE clusters because:

  1. Atlas always returns analyticsSpecs in responses (even with nodeCount: 0)
  2. When clearing storage_config, shardSizeLimitRemoved returns true, which sets ForceUpdateAttr = ["replicationSpecs"]
  3. ForceUpdateAttr forces the entire replicationSpecs tree into the PATCH, including unchanged attributes
  4. The plan's analyticsSpecs became {"nodeCount": 0} without instanceSize because:
    • The plan modifier doesn't copy analyticsSpecs from state when nodeCount == 0 (to avoid ANALYTICS_INSTANCE_SIZE_MUST_MATCH errors)
    • CopyUnknowns copies nodeCount from state but keeps instanceSize unknown (because auto-scaling is enabled, which adds instance_size to keepUnknown)
  5. Atlas correctly rejected this with 400

CORE clusters don't have this issue because shardSizeLimitRemoved returns false (CORE doesn't have storageConfig), so ForceUpdateAttr is not set and only changed attributes are included in the PATCH.

The Approach: Why ForceUpdateAttr + omitInvalidInfiniteConfig

Why ForceUpdateAttr is needed:

The Atlas API requires the entire replicationSpecs object to be present in the PATCH request to clear shardSizeLimitGB. Without ForceUpdateAttr:

  • State: storageConfig is not present (Atlas doesn't return it after clearing)
  • Plan: storageConfig is not present (user removed it from config)
  • Result: No diff detected → no PATCH sent → limit is not cleared

ForceUpdateAttr forces the entire replicationSpecs into the PATCH, which tells Atlas to clear the field.

Why omitInvalidInfiniteConfig is needed:

When ForceUpdateAttr forces the entire replicationSpecs into the PATCH, it includes ALL fields, not just the ones that changed. This includes analyticsSpecs with nodeCount=0 but no instanceSize, which INFINITE rejects.

omitInvalidInfiniteConfig removes invalid fields from the PATCH payload before sending it to Atlas.

Why this asymmetry exists:

The asymmetry between CORE and INFINITE is inherent to the feature:

  • Only INFINITE supports storageConfig (shardSizeLimitGB)
  • Only INFINITE needs to clear it
  • CORE doesn't have this field, so it doesn't need this logic

This is not a bug - it's a reflection of the different capabilities of CORE and INFINITE clusters.

The Fix

  1. Renamed omitEmptyAutoScalingChildrenomitInvalidInfiniteConfig: The function now handles more than just auto-scaling children - it also omits analyticsSpecs without instanceSize that INFINITE rejects. The new name better reflects its purpose.

  2. Added analyticsSpecs removal logic: When nodeCount=0 and instanceSize is not set, the function now sets analyticsSpecs = nil to prevent Atlas from rejecting the PATCH.

Future Improvements

A future PR could explore removing ForceUpdateAttr entirely by using a different mechanism to detect the removal (e.g., explicitly marking storageConfig for removal in the plan). However, this requires verification that the Atlas API accepts this approach and is out of scope for this fix.

Link to any related issue(s): CLOUDP-447210

Type of change:

  • Bug fix (non-breaking change which fixes an issue). Please, add the "bug" label to the PR.
  • New feature (non-breaking change which adds functionality). Please, add the "enhancement" label to the PR. A migration guide must be created or updated if the new feature will go in a major version.
  • Breaking change (fix or feature that would cause existing functionality to not work as expected). Please, add the "breaking change" label to the PR. A migration guide must be created or updated.
  • This change requires a documentation update
  • Documentation fix/enhancement

Required Checklist:

  • I have signed the MongoDB CLA
  • I have read the contributing guides
  • I have checked that this change does not generate any credentials and that they are NOT accidentally logged anywhere.
  • I have added tests that prove my fix is effective or that my feature works per HashiCorp requirements
  • I have added any necessary documentation (if appropriate)
  • I have run make fix and verified my code
  • If changes include deprecations or removals I have added appropriate changelog entries.
  • If changes include removal or addition of 3rd party GitHub actions, I updated our internal document. Reach out to the APIx Integration slack channel to get access to the internal document.

Further comments

…ompute auto-scaling

Add test steps to verify Atlas returns 400 (not 500) when clearing
storage_config while compute auto-scaling stays configured.

Refs: CLOUDP-447210
When clearing storage_config on an INFINITE cluster, the forced
replicationSpecs PATCH included analyticsSpecs with nodeCount=0 but
no instanceSize, causing Atlas to return 400 MISSING_ATTRIBUTE.

The fix omits analyticsSpecs entirely when nodeCount=0 and instanceSize
is not set, which is the correct behavior for INFINITE clusters.

Fixes: CLOUDP-447210
@github-actions github-actions Bot added the bug label Sep 18, 2026
@lantoli lantoli changed the title fix: Omit analyticsSpecs without instanceSize in INFINITE PATCH payloads chore: Omit analyticsSpecs without instanceSize in INFINITE PATCH payloads Sep 18, 2026
@github-actions github-actions Bot removed the bug label Sep 18, 2026
…onfig

The function now handles more than just auto-scaling children - it also
omits analyticsSpecs without instanceSize that INFINITE rejects. The new
name better reflects its purpose.
@lantoli lantoli changed the title chore: Omit analyticsSpecs without instanceSize in INFINITE PATCH payloads fix: Omit analyticsSpecs without instanceSize in INFINITE PATCH payloads Sep 18, 2026
@github-actions github-actions Bot added the bug label Sep 18, 2026
@lantoli lantoli changed the title fix: Omit analyticsSpecs without instanceSize in INFINITE PATCH payloads chore: Omit analyticsSpecs without instanceSize in INFINITE PATCH payloads Sep 18, 2026
@github-actions github-actions Bot removed the bug label Sep 18, 2026
…ero-node analytics

Add test case to verify that clearing storage_config works when
analytics_specs is explicitly configured with node_count = 0. This
tests the edge case where analyticsSpecs would be included in the
PATCH without instanceSize.
…sSpecs

The comment incorrectly suggested that only INFINITE rejects analyticsSpecs
without instanceSize. In reality, Atlas rejects this for all cluster types,
but the bug only manifests for INFINITE because ForceUpdateAttr forces the
entire replicationSpecs into the PATCH.
…Config

- Update comments in model_to_ClusterDescription20240805.go and resource.go
  to reflect that the function now handles more than just empty auto-scaling
  children (also analyticsSpecs without instanceSize).
- Remove redundant comment in configDatabaseEditionWithZeroNodeAnalytics
  that repeated information already in the test function comment.
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.

1 participant