Golang CDK: synth fails when using lazy string due to circular reference
Describe the bug
This is probably specific to the Go CDK bindings, or it is also possible I am misunderstanding the use of the lazy string mechanism. When I try to use the awscdk.Lazy_String method for e.g. a log group name, synth fails due to a circular reference:
$ CDK_DEBUG=true cdk synth
panic: TypeError: Resolution error: Resolution error: Resolution error: Converting circular structure to JSON
--> starting at object with constructor 'CfnLogGroup'
| property 'node' -> object with constructor 'Node'
--- property 'host' closes the circle.
Object creation stack:
at Lazy.string (/tmp/jsii-kernel-u0LhzS/node_modules/aws-cdk-lib/core/lib/lazy.js:1:953)
at /tmp/jsii-runtime.3237986321/lib/program.js:9876:152
at Kernel._Kernel_ensureSync (/tmp/jsii-runtime.3237986321/lib/program.js:10480:24)
at Kernel.sinvoke (/tmp/jsii-runtime.3237986321/lib/program.js:9876:102)
at KernelHost.processRequest (/tmp/jsii-runtime.3237986321/lib/program.js:11696:36)
at KernelHost.run (/tmp/jsii-runtime.3237986321/lib/program.js:11656:22)
at Immediate._onImmediate (/tmp/jsii-runtime.3237986321/lib/program.js:11657:46)
at process.processImmediate (node:internal/timers:476:21)..
See below for a very simple example that reproduces the issue.
Expected Behavior
Able to use the awscdk.Lazy_String function.
Current Behavior
Synth fails when using the awscdk.Lazy_String function.
Reproduction Steps
Complete example:
package main
import (
"github.com/aws/aws-cdk-go/awscdk/v2"
"github.com/aws/aws-cdk-go/awscdk/v2/awslogs"
"github.com/aws/jsii-runtime-go"
)
type LazyString struct{}
func (l *LazyString) Produce() *string {
s := "value"
return &s
}
func main() {
defer jsii.Close()
app := awscdk.NewApp(nil)
stack := awscdk.NewStack(app, jsii.String("stack"), &awscdk.StackProps{})
lazy := &LazyString{}
awslogs.NewLogGroup(stack, jsii.String("log-group"), &awslogs.LogGroupProps{
LogGroupName: awscdk.Lazy_String(lazy, &awscdk.LazyStringValueOptions{}),
})
app.Synth(nil)
}
Then just run cdk synth, and it will fail.
Possible Solution
No response
Additional Information/Context
No response
CDK CLI Version
2.137.0 (build bb90b4c)
Framework Version
No response
Node.js Version
18.18.2
OS
Linux
Language
Go
Language Version
go version go1.20.12 linux/amd64
Other information
No response
Reproducible.
-
Similar code below in TypeScript works:
import * as cdk from 'aws-cdk-lib'; import * as awslogs from 'aws-cdk-lib/aws-logs'; import { TypescriptStack } from '../lib/typescript-stack'; const app = new cdk.App(); const stack = new cdk.Stack(app, 'MyStack'); new awslogs.LogGroup(stack, 'log-group', { logGroupName: cdk.Lazy.string({ produce() { return 'value'; }}) }); -
.NET code:
using Amazon.CDK; using Amazon.CDK.AWS.Logs; namespace Dotnet { sealed class Program { public static void Main(string[] args) { var app = new App(); var stack = new Stack(app, "MyStack"); new LogGroup(stack, "log-group", new LogGroupProps() { LogGroupName = Lazy.String(new Producer()) }); app.Synth(); } class Producer : IStableStringProducer { public string Produce() { return "value"; } } } }fails with below error:
Unhandled exception. System.ArgumentException: Could not convert argument 'Dotnet.Program+Producer' to Jsii (Parameter 'arguments') at Amazon.JSII.Runtime.Deputy.DeputyBase.<>c__DisplayClass20_0.<ConvertArguments>b__0(Parameter parameter, Object frameworkArgument) at System.Linq.Enumerable.ZipIterator[TFirst,TSecond,TResult](IEnumerable`1 first, IEnumerable`1 second, Func`3 resultSelector)+MoveNext() at System.Collections.Generic.LargeArrayBuilder`1.AddRange(IEnumerable`1 items) at System.Collections.Generic.EnumerableHelpers.ToArray[T](IEnumerable`1 source) at Amazon.JSII.Runtime.Deputy.DeputyBase.ConvertArguments(Parameter[] parameters, Object[] arguments) at Amazon.JSII.Runtime.Deputy.DeputyBase.<InvokeMethodCore>g__GetResult|18_0[T](<>c__DisplayClass18_0`1& ) at Amazon.JSII.Runtime.Deputy.DeputyBase.InvokeMethodCore[T](JsiiMethodAttribute methodAttribute, Object[] arguments, Func`3 beginFunc, Func`3 invokeFunc) at Amazon.JSII.Runtime.Deputy.DeputyBase.InvokeStaticMethod[T](Type type, Type[] parameterTypes, Object[] arguments, String methodName) at Amazon.CDK.Lazy.String(IStableStringProducer producer, ILazyStringValueOptions options) at Dotnet.Program.Main(String[] args) in /Users/tempuser/dev/repros/cdk/issue29906_go/dotnet/src/Dotnet/Program.cs:line 14 Subprocess exited with error 134 -
There was an issue https://github.com/aws/jsii/issues/1781 for Python which was closed due to staleness.
I hit this bug with python and found a workaround. Taking the example from the CDK Guide:
class Producer:
def __init__(self, func):
self.produce = func
class FixedProducer:
__jsii_type__ = None
def __init__(self, func):
self.func = func
@jsii.member(jsii_name='produce')
def produce(self, context):
return self.func()
Maybe this can be of some use with Go as well?