Skip to content

Conversation

jasonwbarnett
Copy link

@jasonwbarnett jasonwbarnett commented Oct 14, 2025

Fixes #60

Summary

This PR fixes value conversion errors that occur when the Entitle API returns null values for optional fields like integration, workflow, allowed_durations, and maintainers. The provider now properly handles null values and prevents drift detection when these fields are null in both the configuration and API response.

Changes

  • Changed Integration and Workflow fields to pointer types (*utils.IdNameModel) to handle null values
  • Added nil checks in Create/Read/Update functions to safely handle null integration and workflow objects
  • Updated convertFullResourceResultResponseSchemaToModel function to preserve null values for allowed_durations and maintainers instead of converting them to empty arrays
  • Added UseStateForUnknown() plan modifiers to computed name fields within integration and workflow nested attributes to prevent drift on read-only fields
  • Removed Computed: true from allowed_durations and maintainers schema - having both Optional and Computed caused value conversion errors during updates
  • Fixed Update function to only send Owner and Workflow pointers when populated - prevents 404 errors from API when sending empty structs
  • Added TestResourceResourceNullFields acceptance test to verify null handling behavior

Testing

  • Added new acceptance test TestResourceResourceNullFields that:
    • Creates a resource with minimal required fields (no allowed_durations, no maintainers)
    • Verifies no drift occurs when re-applying the same configuration
    • Verifies import works correctly without showing drift
  • Manually tested import functionality with actual resources
  • Verified terraform plan shows "No changes" after import
  • Validated bidirectional requestable field updates (true ↔ false)
  • Confirmed Update operations succeed without 404 errors

Technical Details

The root cause was that non-pointer struct types in Go cannot represent null values. When the API returned null for optional nested objects like integration or workflow, the Terraform Plugin Framework couldn't convert these null values to the non-nullable utils.IdNameModel struct type.

Additionally, optional fields marked as Computed: true caused Terraform to treat them as "unknown" during update operations, leading to "Value Conversion Error" when trying to convert unknown values to Go slice types.

The fix:

  1. Converts Integration and Workflow fields to pointer types with comprehensive nil checks
  2. Removes Computed: true from optional list/set fields to prevent unknown value errors
  3. Only sends optional fields in Update requests when they have actual values

🤖 Generated with Claude Code

Co-Authored-By: Claude [email protected]

jasonwbarnett and others added 6 commits October 13, 2025 12:30
The Entitle API does not support updating the name field after resource
creation (IntegrationResourcesUpdateBodySchema does not include a Name field).
However, the Terraform schema marked it as Required without any plan modifier,
causing Terraform to attempt updates when the name changed.

This fix adds the RequiresReplace plan modifier to the name attribute,
ensuring that any name change will trigger a destroy-and-recreate cycle
rather than an in-place update attempt.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
Add TestResourceResourceNullFields to verify that optional fields like
allowed_durations and maintainers handle null values correctly without
causing drift during import or plan operations.

The test verifies:
- Resources can be created with minimal required fields
- Null values don't cause plan drift
- Import state verification works correctly with null fields

Relates to entitleio#60

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
…nal fields

This commit fixes two issues with optional field handling:

1. Removed `Computed: true` from `allowed_durations` and `maintainers` schema
   attributes. Having both `Optional` and `Computed` set caused Terraform to
   treat these fields as "unknown" during updates, leading to value conversion
   errors.

2. Updated the Update function to only send `Owner` and `Workflow` pointers
   when they have values. Previously, empty structs were being sent to the API,
   causing 404 errors during resource updates.

These changes ensure that:
- Optional fields can be omitted from configuration without causing errors
- Update operations succeed when optional fields are null
- No drift is detected for legitimately null optional fields

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
When allowed_durations is not specified in terraform config, the provider
now sends null to the API instead of an empty array. This tells the API
to use the workflow's default durations instead of requiring at least one
duration to be specified.

Changes:
- Modified ConvertTerraformSetToAllowedDurations to return *[]EnumAllowedDurations
- Returns nil when terraform value is null (use workflow defaults)
- Returns pointer to slice when value is specified
- Updated Create and Update functions to use pointer return value

Fixes the "must have at least one allowed duration" error when
allowed_durations field is omitted from resource configuration.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
Previously, removing all maintainers would cause "Provider produced
inconsistent result" error. The fix ensures empty maintainers list
is properly sent to the API, allowing maintainers to be removed.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
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.

Fix: Handle null values in optional fields to prevent value conversion errors

1 participant