fix: emit dynamic attribute for self-referential schemas to prevent stack overflow - #2
Draft
claude[bot] wants to merge 2 commits into
Draft
fix: emit dynamic attribute for self-referential schemas to prevent stack overflow#2claude[bot] wants to merge 2 commits into
claude[bot] wants to merge 2 commits into
Conversation
…tack overflow Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011drBEhNrtGfnXQNsedmJLa
Update NewResourceMapper/NewDataSourceMapper/NewProviderMapper test call sites to pass the *high.Document parameter added by the discriminator support commit (0dffe9d) but never updated in the mapper test files, which broke compilation of the internal/mapper test package. Also fix the stale TestBuildSchema_Errors/too_many_allOf case: that same commit added composeAllOfSchemas to legitimately support composing multiple allOf subschemas (for inheritance patterns), so allOf with more than one subschema is no longer an error. Remove the obsolete error-path fixture and add a passing coverage case to TestBuildSchema_AllOfSchemaComposition verifying multi-schema property merging.
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.
Requested by Brady Burke · Slack thread
Before / After
Before: Running the OpenAPI codegen (
tfplugingen-openapi) on a genuinely self-referential schema crashed the whole process with an unrecoverablefatal error: stack overflow. The Galaxy API'sIngestColumn/NewJsonIngestColumnInSchemaUpdateschema has anestedColumnsarray whose items$refback to the enclosing schema (it models arbitrarily-nested ingest columns). The attribute builder had no cycle or depth tracking, so it recursed into that same property forever and took down generation of theingest_columnresource entirely.After: The builder detects the reference cycle and, at the point where the recursive edge would re-enter a type already open on the descent path, emits that one attribute as a Terraform
dynamicattribute instead of recursing. Generation now succeeds, theingest_columnresource is produced, and the recursive structure is still authorable (as a dynamic value). Everything else in the schema stays strongly typed — only the self-referential edge degrades to dynamic. Terraform's plugin framework has no recursive nested type, sodynamicis the correct representation (preferred over erroring/skipping the resource, or flattening the field to a JSON string).How
VisitedRefs map[string]boolset toGlobalSchemaOpts(which already threads through the whole builder chain), with aWithVisitedRefhelper that returns a copy with a ref added so sibling branches never share mutation, and anIsVisitedRefhelper.BuildSchemarecords a schema's$refin the visited set as it descends through it, so deeper builders can tell when they are re-entering a type already open on the path (a cycle).BuildCollection{Resource,DataSource,Provider}(the array case that the real schema hits) and in the object-property loops inattribute.go(direct object self-refs), if the item/property references an already-visited schema, the attribute is built via the newBuildDynamic{Resource,DataSource,Provider}helpers rather than recursing.internal/mapper/oas/dynamic.go(builders) andinternal/mapper/attrmapper/dynamic.go(Resource/DataSource/ProviderDynamicAttribute, mirroring the existingstringattrmapper types and using the spec'sDynamicattribute type).collection_test.gobuilds an object whosenested_columnsarray items$refback to the enclosing schema and asserts the result is a*attrmapper.ResourceDynamicAttributeand that the build returns instead of overflowing.Cross-dependency
The downstream tool
terraform-plugin-codegen-frameworkmust be able to consume a spec that now contains adynamicattribute. That fork did not previously support dynamic attributes; support is added in the companion PR starburstdata/terraform-plugin-codegen-framework#3. Both are needed for the end-to-end codegen pipeline to succeed on the recursive schema.Base branch note
This branch is based on the exact commit the provider pins (
a3f0d68, the resolved SHA of pseudo-versionv0.0.0-20250916180948-a3f0d6803323) so the fix is directly consumable by the provider.mainis one commit ahead (c3e7ba4, "sensitive override support"); that commit touches only the scalarattrmapperfiles and does not conflict with this change, so it merges cleanly intomain.Pre-existing test failures (also fixed in this PR)
Two test failures were present on the base commit, unrelated to the dynamic-attribute fix above. Brady asked for these to be repaired here as well, so the branch is fully green:
TestBuildSchema_Errors/too_many_allOf: stale test fixture. The earlier discriminator-support commit (0dffe9d) addedcomposeAllOfSchemas, which intentionally merges properties across multipleallOfsubschemas (needed for inheritance-style composition) instead of erroring. The test still expected the old "schema composition is currently not supported" error forlen(allOf) > 1, which no longer occurs. Removed the obsolete error-path fixture and added a passing case toTestBuildSchema_AllOfSchemaCompositionthat verifies twoallOfobject subschemas correctly merge their properties.internal/mapper/*_mapper_test.gobuild failure: the same discriminator-support commit added a*high.Documentparameter toNewResourceMapper,NewDataSourceMapper, andNewProviderMapper(needed to resolve$refs in discriminator mappings), but the test call sites inresource_mapper_test.go,datasource_mapper_test.go, andprovider_mapper_test.gowere never updated, so theinternal/mappertest package failed to compile. Updated the four call sites to passnilfor the document (none of those test cases exercise discriminator resolution).go build ./...andgo test ./...are both clean on this branch now.Generated by Claude Code