Skip to main content
← Back to list
01Issue
BugOpenExtensionsPublic
AssigneesNone

Relationships

#2487 Generated @swamp/aws StateSchemas mark conditional and create-only properties as required, producing schema warnings on every read

Opened by kscarmardo-glu · 9/24/2026

Summary

@swamp/aws/eks/cluster emits a schema-validation warning on every get and sync:

warning Resource 'state' data does not match schema:
  Invalid input: expected string, received undefined at "KubernetesNetworkConfig.ServiceIpv6Cidr";
  Invalid input: expected boolean, received undefined at "AccessConfig.BootstrapClusterCreatorAdminPermissions"

The data still writes correctly and in full, so this is noise rather than breakage. But the two fields named are not the whole problem — they are the only two that happen to be visible.

The underlying issue

StateSchema in models/cluster.ts declares 73 required fields. 40 of them are never returned by DescribeCluster.

KubernetesNetworkConfig.ServiceIpv6Cidr          AccessConfig.BootstrapClusterCreatorAdminPermissions
OutpostConfig.OutpostArns                        OutpostConfig.ControlPlaneInstanceType
OutpostConfig.ControlPlanePlacement              OutpostConfig.EtcdInstanceType
OutpostConfig.EtcdPlacement                      RemoteNetworkConfig.RemoteNodeNetworks
RemoteNetworkConfig.RemotePodNetworks            ComputeConfig.NodeRoleArn
ResourcesVpcConfig.ControlPlaneEgressMode        RollbackConfig.TimeoutMinutes
ZonalShiftConfig.Enabled                         ControlPlaneScalingConfig.Tier
KubeApiServerConfig.EventTtl                     KubeApiServerConfig.ServiceNodePortRange
KubeSchedulerConfig.NodeResourcesFit             CertificateAuthority.Active.Id
BootstrapSelfManagedAddons                       ActiveCertificateAuthorityId
… 40 total

These fall into two groups, neither of which can ever be satisfied:

  • Create-only parameters. BootstrapClusterCreatorAdminPermissions and BootstrapSelfManagedAddons are accepted by CreateCluster and never returned by DescribeCluster — confirmed against a cluster that explicitly set bootstrapClusterCreatorAdminPermissions: false at creation.
  • Conditional feature blocks. OutpostConfig, RemoteNetworkConfig, ZonalShiftConfig, KubeApiServerConfig and friends are only present when that feature is in use. ServiceIpv6Cidr only appears when ipFamily is ipv6.

Why only two surface

Zod validates a nested object's children only when the parent object is present. OutpostConfig is absent wholesale, so its five required children never produce an error. KubernetesNetworkConfig and AccessConfig are returned, so their missing children do.

The other 38 are masked by their own absent parents — and would surface the moment someone runs a cluster that uses one of those features. A user enabling Outposts or zonal shift would suddenly see new warnings on a cluster that was previously quiet.

Reproduction

swamp extension pull @swamp/aws/eks
swamp model create @swamp/aws/eks/cluster my-clusters \
  --global-arg region=<region> --global-arg Name=<cluster> \
  --global-arg RoleArn=<role-arn> \
  --global-arg ResourcesVpcConfig='{"SubnetIds":["subnet-…","subnet-…"]}'
swamp model method run my-clusters get --input identifier=<cluster>

Warns on every run, on any IPv4 cluster.

Scope

Likely systemic across generated @swamp/aws/* types rather than specific to EKS — the same generator produces the read schemas for every service, and the same two categories (create-only parameters, conditional feature blocks) exist throughout the AWS resource schemas. I have only measured eks/cluster.

Within the same extension, the input/create schemas get this right — BootstrapClusterCreatorAdminPermissions is .optional() at both models/cluster.ts:240 and :512, and required only at :379 inside StateSchema. So the read path is the outlier, not the intent.

Suggested fix

At the generator, on the read/state path: treat a property as required only where the AWS resource schema guarantees it on read. Create-only and conditional properties should be .optional().

Patching the two visible fields by hand would silence the warning while leaving the other 38 to appear later, on someone else's cluster.

Environment

  • swamp 20260923.133857.0-sha.819937e2
  • @swamp/aws/eks 2026.09.23.1
  • model type @swamp/aws/eks/cluster 2026.08.29.1
  • macOS (darwin-aarch64)
02Bog Flow
◉OPEN○TRIAGED○IN PROGRESS○SHIPPED

Open

9/24/2026, 3:29:46 PM

No activity in this phase yet.

03Sludge Pulse
Editable. Press Enter to edit.

system commented 9/24/2026, 3:29:47 PM

Classified automatically when this issue was filed.

  • Source: Extensions

If you feel this classification is incorrect, add a ripple to tell us so.

kscarmardo-glu commented 9/24/2026, 10:18:46 PM

A second instance of this, in a different service, which suggests the generator rather than the EKS schema.

@swamp/aws/certificatemanager/certificate get returns only:

['CertificateArn', 'DomainName', 'KeyAlgorithm', 'SubjectAlternativeNames', '_identifier']

Absent: NotAfter, NotBefore, Type, Status, RenewalEligibility, InUseBy — every field ACM's own DescribeCertificate returns and that you would actually read a certificate to find out.

Same root cause as the EKS case, seen from the other side. There the read schema marked declare-time properties as required on read; here the read schema omits report-time properties altogether. Both follow from generating the read path from a resource schema that describes what can be declared rather than what the service reports.

Concretely, this makes the model unable to answer the question that matters for certificates. We hit a wildcard cert three days from expiry that was Type: IMPORTED with RenewalEligibility: INELIGIBLE — it would never auto-renew, and nothing in the model surfaces that. An AMAZON_ISSUED certificate 3 days out is unremarkable; an IMPORTED one is an outage. The model cannot distinguish them.

Worth considering whether the generator should union the resource schema with the service's describe/read shape for read methods, rather than treating the declarable surface as the whole model.

Sign in to post a ripple.