aws / aws/jsii

Kernel: Serialization does ignore actual type when trying wireTypes in unions

Open
#4,547 1 comment 0 reactions 0 assignees View on GitHub
bug module/kernel p2
Dominant language
TypeScript
Stars
2.9k
Forks
267
Avg merge
1d 25m
Merged PRs (30d)
14

Description

### Describe the bug

When sending a value from the jsii-kernel back to the caller (<), if the type is a union the serializer just uses a fixed order to try an serialize the type. However in a union type like `CfnBucket.CorsConfigurationProperty | cdk.IResolvable`, if the actual value is an `cdk.IResolvable` (e.g. a `Lazy.Any`) the code still serializes the value as the struct type.

This is wrong, but also doesn't work because a language runtime like Python might then recurse into the struct fields and request nested values to build a struct on the language-side. Instead this should be returned as a `ReferenceType`.

### Expected Behavior

Serialize as a `ReferenceType`

### Current Behavior

Serialized as a `StructType`

### Reproduction Steps

Not quite sure, but the easiest seems to be if the jsii needs to return a `Lazy.Any` (<) that is typed as something like `CfnBucket.CorsConfigurationProperty | cdk.IResolvable`

### Possible Solution

This fixes the issue on my end:

```ts
export function process(
host: SerializerHost,
serde: keyof Serializer,
value: unknown,
type: OptionalValueOrVoid,
context: string,
) {
const wireTypes = serializationType(type, host.lookupType).filter(
({ serializationClass }) => {
if (
serde === 'serialize' &&
serializationClass === SerializationClass.Struct
) {
return (value as any)?.constructor.name !== 'LazyAny';
// return !isByReferenceOnly(value);
}
return true;
},
);
```

Unfortunately just always using `return !isByReferenceOnly(value);` causes more problems and for obvious reasons checking the constructor name is not a good idea. I suspect this check needs to be more clever in the way filters the proposed wireType in relation to the actual value.

### SDK version used

1.99.0

### Environment details (OS name and version, etc.)

any

Contributor guide

Open the contributing guide

Research direction

Start at process(), especially its serializationType() wireTypes filtering and the SerializationClass.Struct branch. Trace how Lazy.Any values in unions are classified, then verify that an actual reference-like value is serialized as ReferenceType rather than StructType; the issue provides no specific file or regression test to run.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
backend
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.