ses: DedicatedIpPool rejects a tokenized dedicatedIpPoolName
- Dominant language
- TypeScript
- Stars
- 12.9k
- Forks
- 4.6k
- Avg merge
- 1d 19h
- Merged PRs (30d)
- 74
Description
### Describe the bug
`ses.DedicatedIpPool` validates `dedicatedIpPoolName` with a regex but does not first check `Token.isUnresolved()`. Any name that is not a literal string — `Fn.importValue()`, a `CfnParameter` value, or another resource's attribute — is still an unresolved token at construction time, rendering as `${Token[TOKEN.123]}`. That placeholder cannot match `/^[a-z0-9_-]{0,64}$/`, so synthesis throws even though the value CloudFormation eventually resolves is perfectly valid.
The error message itself shows the token, which makes the cause visible:
```
Invalid dedicatedIpPoolName "${Token[TOKEN.1222]}". The name must only include lowercase
letters, numbers, underscores, hyphens, and must not exceed 64 characters.
```
Source: [`aws-ses/lib/dedicated-ip-pool.ts`](https://github.com/aws/aws-cdk/blob/main/packages/aws-cdk-lib/aws-ses/lib/dedicated-ip-pool.ts#L104)
```ts
if (props.dedicatedIpPoolName && !/^[a-z0-9_-]{0,64}$/.test(props.dedicatedIpPoolName)) {
throw new ValidationError(...);
}
```
This is the pattern [`AGENTS.md` § Token Safety](https://github.com/aws/aws-cdk/blob/main/AGENTS.md) explicitly calls out:
> Check `Token.isUnresolved()` before any validation on tokenized values
### Regression Issue
- [ ] Select this option if this issue appears to be a regression.
### Last Known Working CDK Version
_No response_
### Expected Behavior
A tokenized pool name should skip the synth-time name check and be passed through to CloudFormation, the same way other CDK constructs treat tokenized physical names. The following should synthesize:
```ts
new ses.DedicatedIpPool(this, 'Pool', {
dedicatedIpPoolName: Fn.importValue('SharedPoolName'),
});
```
producing:
```json
{ "Type": "AWS::SES::DedicatedIpPool", "Properties": { "PoolName": { "Fn::ImportValue": "SharedPoolName" } } }
```
### Current Behavior
Synthesis throws `InvalidDedicatedIpPoolName`. There is no workaround other than hardcoding the name, which defeats the purpose of importing it.
### Reproduction Steps
```ts
import { App, CfnParameter, Fn, Stack } from 'aws-cdk-lib';
import * as ses from 'aws-cdk-lib/aws-ses';
const stack = new Stack(new App(), 'S');
// Both of these throw at synthesis:
new ses.DedicatedIpPool(stack, 'PoolA', {
dedicatedIpPoolName: Fn.importValue('SharedPoolName'),
});
const p = new CfnParameter(stack, 'PoolName', { type: 'String' });
new ses.DedicatedIpPool(stack, 'PoolB', {
dedicatedIpPoolName: p.valueAsString,
});
```
A literal name (`dedicatedIpPoolName: 'my-pool'`) works, so the failure is specific to tokenized values.
### Possible Solution
Add the standard guard, leaving validation of literal names unchanged:
```ts
if (props.dedicatedIpPoolName && !Token.isUnresolved(props.dedicatedIpPoolName) &&
!/^[a-z0-9_-]{0,64}$/.test(props.dedicatedIpPoolName)) {
throw new ValidationError(...);
}
```
This only loosens validation for values that could never be checked correctly in the first place, so it is backwards compatible — no previously-synthesizing app changes behavior, and no feature flag is needed.
### Additional Information/Context
_No response_
### CDK CLI Version
2.x
### Framework Version
_No response_
### Node.js Version
v24.1.0
### OS
macOS
### Language
TypeScript
### Language Version
_No response_
### Other information
_No response_
Contributor guide
Research direction
Start in packages/aws-cdk-lib/aws-ses/lib/dedicated-ip-pool.ts at the dedicatedIpPoolName validation described in the issue, and review AGENTS.md § Token Safety. Verify that unresolved names synthesize to the expected CloudFormation property while literal invalid names still fail validation.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- aws, typescript
- Domain
- cloud
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 78/100