Summary
cdk watch hangs indefinitely — with no error, progress, or fallback — when a watched stack declares a CfnParameter that has no default. The hotswap template evaluator can't resolve the parameter, and instead of erroring or falling back, watch silently sits at deploying... forever.
Environment
aws-cdk (CLI): 2.1128.0 (build 7daa104)
aws-cdk-lib: 2.258.1
- node:
v24.12.0
- OS: macOS
26.5.1 (Darwin)
Reproduction
A stack that declares a parameter without a default, plus a hotswappable resource:
new cdk.CfnParameter(this, 'Foo', { type: 'String' }); // no default
new lambda.Function(this, 'Fn', { /* inline code */ });
cdk watch (after the stack already exists, so watch attempts a hotswap) prints MyStack: deploying... and then hangs forever — no progress, no error, no hotswap, no fallback. CPU idle, no network.
cdk deploy --hotswap MyStack of the same stack does not hang.
- Adding
default: '' to the parameter, or removing the parameter, fixes the hang.
- Passing
--parameters does not help (hotswap's read-only template evaluation appears to resolve from template defaults, not CLI --parameters).
Analysis
This looks like the hotswap template evaluator failing to resolve a parameter with no default (cf. aws/aws-cdk#22323), but in watch it manifests as a silent infinite hang rather than an error or fallback.
Expected
Error out (or fall back to a full CloudFormation deployment), not hang silently.
Workaround
Give every CfnParameter a default so the hotswap evaluator can resolve it; the real value is still supplied at deploy via --parameters (which overrides the default), and cdk deploy falls back correctly when there's a non-hotswappable change:
new cdk.CfnParameter(this, 'Foo', { type: 'String', default: '' }); // unblocks watch
Better still (AWS recommends against CfnParameter with CDK): avoid the parameter entirely — resolve the value at synth (context/env) or, for secrets, via a CloudFormation dynamic reference such as cdk.SecretValue.secretsManager(...) / {{resolve:secretsmanager:...}}, which keeps the value out of the template and leaves no CfnParameter for the evaluator to choke on. (Note: Cognito UserPoolIdentityProvider.ProviderDetails accepts secretsmanager dynamic references but not ssm-secure ones.)
Related
- aws/aws-cdk#22323 — hotswap deploy fails on
CfnEvaluationException (same template-evaluator root cause; here it surfaces as a silent hang in watch rather than an error).
Summary
cdk watchhangs indefinitely — with no error, progress, or fallback — when a watched stack declares aCfnParameterthat has nodefault. The hotswap template evaluator can't resolve the parameter, and instead of erroring or falling back, watch silently sits atdeploying...forever.Environment
aws-cdk(CLI):2.1128.0(build 7daa104)aws-cdk-lib:2.258.1v24.12.026.5.1(Darwin)Reproduction
A stack that declares a parameter without a
default, plus a hotswappable resource:cdk watch(after the stack already exists, so watch attempts a hotswap) printsMyStack: deploying...and then hangs forever — no progress, no error, no hotswap, no fallback. CPU idle, no network.cdk deploy --hotswap MyStackof the same stack does not hang.default: ''to the parameter, or removing the parameter, fixes the hang.--parametersdoes not help (hotswap's read-only template evaluation appears to resolve from template defaults, not CLI--parameters).Analysis
This looks like the hotswap template evaluator failing to resolve a parameter with no default (cf. aws/aws-cdk#22323), but in
watchit manifests as a silent infinite hang rather than an error or fallback.Expected
Error out (or fall back to a full CloudFormation deployment), not hang silently.
Workaround
Give every
CfnParameteradefaultso the hotswap evaluator can resolve it; the real value is still supplied at deploy via--parameters(which overrides the default), andcdk deployfalls back correctly when there's a non-hotswappable change:Better still (AWS recommends against
CfnParameterwith CDK): avoid the parameter entirely — resolve the value at synth (context/env) or, for secrets, via a CloudFormation dynamic reference such ascdk.SecretValue.secretsManager(...)/{{resolve:secretsmanager:...}}, which keeps the value out of the template and leaves noCfnParameterfor the evaluator to choke on. (Note: CognitoUserPoolIdentityProvider.ProviderDetailsacceptssecretsmanagerdynamic references but notssm-secureones.)Related
CfnEvaluationException(same template-evaluator root cause; here it surfaces as a silent hang inwatchrather than an error).