You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: AGENTS.md
+27-3Lines changed: 27 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -175,12 +175,36 @@ Tokens can encode strings, numbers, and lists. Any object implementing `IResolva
175
175
- Use `Tokenization.stringifyNumber()` to safely convert a possibly-tokenized number to string
176
176
- Don't use resource attributes (Tokens) in hash calculations for physical names
177
177
178
-
### Lazy Values
178
+
### Deferred Values (Box API)
179
+
180
+
L2 constructs that accumulate state after construction (e.g., adding actions, policy statements, security groups) MUST use the **Box API** to defer value resolution — not `Lazy`. Boxes implement `IResolvable` and capture stack traces at mutation call sites (under `CDK_DEBUG`), enabling accurate property attribution in synthesized templates.
181
+
182
+
- Use `Box.fromArray<T>([])` for accumulator lists, `Box.fromValue<T>(initial)` for single values, `Box.fromMap<K,V>()` for maps, `Box.fromSet<A>()` for sets
183
+
- Pass to L1 props via `Token.asList(box)`, `Token.asString(box)`, `Token.asNumber(box)`, or `Token.asAny(box)` for complex/object values
184
+
-`Box.fromArray` resolves to `undefined` when empty (omitEmpty default) — no manual empty-array check needed. Pass `{ omitEmpty: false }` to resolve to an empty array instead
185
+
- Mutate via `box.push(item)` or `box.set(newValue)` — each captures a stack trace at the call site
186
+
- Use `box.derive(fn)` for single-source transforms or `Box.combine({ name: box, ... }, ({ name, ... }) => ...)` for multi-source derived values
187
+
- Apply `@noBoxStackTraces` decorator on L2 classes that create or mutate Boxes in their constructor (suppresses irrelevant internal traces)
188
+
- NEVER mutate construct tree in Lazy or Box callbacks
189
+
190
+
`Lazy` is legacy — existing code still uses it but new L2 constructs MUST prefer Boxes. See `packages/aws-cdk-lib/core/adr/box-api.md` for full rationale.
this._actions.push(action); // Stack trace captured HERE — user's code
2091
+
}
2057
2092
}
2058
2093
```
2059
2094
2060
-
`bind()` methods mutate the construct tree, and should not be called from a callback
2061
-
in a `Lazy`.
2095
+
Key rules:
2096
+
-`Box.fromArray([])` for lists, `Box.fromValue(x)` for scalars, `Box.fromMap()` for maps, `Box.fromSet()` for sets
2097
+
- Pass to L1 via `Token.asList(box)`, `Token.asString(box)`, `Token.asNumber(box)`, or `Token.asAny(box)` for complex/object values
2098
+
-`Box.fromArray` resolves to `undefined` when empty by default (no manual empty-array → `undefined` mapping needed). Pass `{ omitEmpty: false }` as the second argument to resolve to an empty array instead
2099
+
- Apply `@noBoxStackTraces` on classes that create or mutate Boxes in their constructor
2100
+
- Use `box.derive(fn)` for single-source transforms, `Box.combine({ a: boxA, b: boxB }, ({ a, b }) => ...)` for multi-source derived values
2101
+
2102
+
See `packages/aws-cdk-lib/core/adr/box-api.md` for the full ADR.
2062
2103
2063
-
* The why:
2064
-
-`Lazy`s are called after the construct tree has already been sythesized. Mutating it
2065
-
at this point could have not-obvious consequences.
2104
+
#### Lazy (legacy)
2105
+
2106
+
`Lazy` remains available and is not deprecated, but new L2 constructs should prefer
2107
+
Boxes for better debuggability. If you must use `Lazy`:
2108
+
2109
+
- Do not use a `Lazy` to perform a mutation on the construct tree
2110
+
-`Lazy`s are resolved after the construct tree has been synthesized — mutating it
2111
+
at that point has non-obvious consequences
2112
+
- For `Lazy.any()` wrapping arrays, pass `{ omitEmptyArray: true }` to resolve empty arrays to `undefined`
2113
+
2114
+
```ts
2115
+
// DO NOT do this — bind() mutates the construct tree
2116
+
this.lazyProperty=Lazy.any({
2117
+
produce: () => {
2118
+
returnprops.logging.bind(this, this); // BAD: tree mutation in Lazy
Copy file name to clipboardExpand all lines: packages/aws-cdk-lib/aws-events/README.md
+2Lines changed: 2 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -379,4 +379,6 @@ const bus = new EventBus(this, 'Bus', {
379
379
});
380
380
```
381
381
382
+
**Note**: Configuring logging on the event bus is required when using [vended logs](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/AWS-logs-and-resource-policy.html). Vended logs require that the event bus has logging enabled with the appropriate log configuration before logs can be delivered to the destination.
383
+
382
384
See more [Specifying event bus log level](https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-event-bus-logs.html#eb-event-bus-logs-level)
0 commit comments