@go-to-k/cdkd 0.290.21 → 0.290.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,8 +1,8 @@
1
- import { $ as secretBearing, $i as withErrorHandling, $n as LockManager, $r as getDefaultStateBucketName, $t as s3BucketArn, A as extractDeploymentEventError, Ai as CdkdError, An as findActionableSilentDrops, Ar as parseBootstrapMarker, At as isImpossibleEmptyStoredAttribute, B as toCfnInteger, Bi as MalformedProducerRecordRefusalError, Bn as carriesSecretMask, Br as dockerSpawnEnvWithSensitive, Bt as coerceCfnBoolean, C as buildFinalSnapshotIdentifier, Cn as refuseMalformedOutputs, Cr as rewriteTemplateAssetReferences, Ct as isTerminationProtectionPropagationError, D as refusesFinalSnapshot, Di as resetAwsClients, Dn as repairMalformedOutputsForReadOnly, Dr as ensureAssetStorage, Dt as cfnRefValueFromPhysicalId, E as isFinalSnapshotError, Ei as getAwsClients, En as refuseMalformedState, Er as assertAssetBucketRegion, Et as carriesFetchableDynamicReference, F as isStatefulRecreateTargetSync, Fi as DynamicReferenceRegionAmbiguousError, Fn as TemplateParser, Fr as describeAwsFailure, Ft as isSettledInstanceState, G as gray, Gi as ResourceUpdateNotSupportedError, Gn as isSingleDynamicReferenceToken, Gr as runDockerForeground, Gt as readConfigString, H as formatResourceLine, Hi as PartialFailureError, Hn as dynamicReferenceTokens, Hr as getDockerCmd, Ht as configBooleanRefusal, I as renderStatefulReason, Ii as IntrinsicResolutionRefusalError, In as STATE_SOURCED_BASELINE_RULES, Ir as buildDockerImage, It as WAFv2WebACLProvider, J as yellow, Jn as maskSecretsInText, Jr as stripControlChars, Jt as requireConfigObject, K as green, Ki as StackHasActiveImportsError, Kn as markSameGenerationBag, Kr as runDockerStreaming, Kt as replayWarn, L as WARM_THROUGHPUT_MEMBERS, Li as LocalInvokeBuildError$1, Ln as STATE_SOURCED_CROSS_GENERATION_RULES, Lr as describeDockerCapturedOutput, Lt as normalizeAwsTagsToCfn, M as planOrphanAdoption, Mi as CrossAccountSecretRefusalError, Mn as describeTypeWithThrottleRetry, Mr as validateAssetBucketName, Mt as isUnboundTemplateParameter, N as MULTI_REGION_RECREATE_BLOCKED_TYPES, Nn as withRetry, Nr as validateContainerRepoName, Nt as parameterTypeMayLoseSecretIdentity, O as unsupportedFinalSnapshotError, Oi as setAwsClients, On as repairMalformedResourcePropertiesForReadOnly, Or as getBootstrapMarkerKey, Ot as coerceParameterTypedValue, P as isStatefulRecreateTargetForReplace, Pi as DeployCancelledError, Pn as DagBuilder, Pr as buildDenyExternalAccessPolicy, Pt as refStateLookupFromResource, Q as isExportAliasCollision, Qi as normalizeAwsError, Qn as scrubResourceRecord, Qr as synthesisStatusMessage, Qt as withSharedDrainBudget, R as coerceWarmThroughput$1, Ri as LocalStartServiceError, Rn as STATE_SOURCED_READBACK_RULES, Rr as describeDockerExecFailure, Rt as resolveExplicitPhysicalId, S as PRE_DELETE_SNAPSHOT_TYPES, Si as processStackMessages, Sn as refuseMalformedNestedChildOutputs, Sr as loadPublishableAssetManifest, St as disableInstanceApiTermination, T as createPreDeleteFinalSnapshot, Ti as AwsClients, Tn as refuseMalformedResourcesForDestroy, Tr as BOOTSTRAP_MARKER_PREFIX, Tt as carriesDynamicReference, U as bold, Ui as ProvisioningError, Un as errorCauseChain, Ur as partitionSensitiveEnv, Ut as configIntegerRefusal, V as toFiniteNumber, Vi as NestedStackChildDirectDestroyError, Vn as createSecretMasker, Vr as formatDockerLoginError, Vt as coerceCfnInteger, W as cyan, Wi as ResourceTimeoutError, Wn as identityKeyFor, Wr as redactDockerArgvValues, Wt as configStringRefusal, X as collectPublishedOutputNames, Xn as recoverMaskedOutput, Xr as getDockerImageBySourceHash, Xt as classifyReplaySecretRegion, Y as collectDeclaredOutputNames, Yn as recordMaskOnlyValue, Yr as AssetManifestLoader, Yt as requireConfigString, Z as exportAliasCollisionScrubWarning, Zn as redactSecretsForState, Zr as Synthesizer, Zt as producerRegionsFromState, _ as isSecretBearingReferenceString, _i as expectedOwnerParam, _n as malformedRenderedContainersWarning, _r as AssetPublisher, _t as isWaitAbandonedError, a as DeploymentEventsStore, aa as markRedactedCause, ai as resolveStateBucketWithDefault, an as applyCallerIdentityCredentials, ar as formatLockExpiry, at as clearOnUpdateRemoval, b as bindingSkippedOutputs, bi as derivePartitionAndUrlSuffix, bn as malformedStateRefusalMessage, br as buildAssetRedirectMap, bt as deleteIndeterminateGuards, c as replayFailedOperations, ci as stateBucketExistenceConfirmed, cn as INTRINSIC_KEYS, cr as DEFAULT_STATE_PREFIX, ct as createMaskedRetryLogger, d as updatePartialReason, di as CFN_TEMPLATE_URL_LIMIT, dn as hasReadableResources, dr as importableOutputKeys, dt as beginCommandInterruptScope, ea as isMarkedNonRetryable, ei as getLegacyStateBucketName, en as s3BucketDomainName, er as S3StateBackend, et as secretBearingStateKeyWarning, f as withResourceDeadline, fi as MIGRATE_TMP_PREFIX, fn as malformedExportNamesWarning, fr as importableOutputs, ft as endCommandInterruptScope, g as bagHoldsSecretExpression, gi as decodeListingKey, gn as malformedOutputsWarning, gr as shouldRetainResource, gt as CloudControlProvider, h as computeImplicitDeleteEdges, hi as CUSTOM_RESOURCE_RESPONSE_OBJECT_DESCRIPTION, hn as malformedOutputsRefusalMessage, hr as orphansCarriedFrom, ht as startInterruptWatch, i as DeploymentEventsReader, ia as markNonRetryable, ii as resolveSkipPrefix, in as applyRoleArnIfSet, ir as forceQuitRecoveryClause, it as collectInlinePolicyNamesManagedBySiblings, j as makeSiblingClaimReader, jn as findSilentDropProperties, jr as readBootstrapMarkerBody, jt as isNamelessDynamicReferenceError, k as makeCanonicalizePropertiesFn, kn as repairMalformedResourcesForReadOnly, kr as isCrossRegionRedirect, kt as getAccountInfo, l as replayRollback, li as warnDeprecatedNoPrefixCliFlag, ln as STATE_RESOURCES_MALFORMED, lr as exportNamesCarriedFrom, lt as maskDeep, m as IMPLICIT_DELETE_DEPENDENCIES, mi as uploadCfnTemplate, mn as malformedLocalOutputsWarning, mr as orphansAfterRollback, mt as isInterruptedWaitError, n as DEFAULT_RESOURCE_WARN_AFTER_MS, na as isThrottlingError, ni as resolveAutoAssetStorage, nn as s3BucketRegionalDomainName, nr as buildForceUnlockCommand, nt as getCurrentResourceSecrets, o as planFailedOps, oa as retryClassificationText, oi as resolveStateBucketWithDefaultAndSource, on as callerEnvCredentials, or as shellQuote, ot as ProviderRegistry, p as maskingRetryLogger, pi as findLargeInlineResources, pn as malformedExportSourceWarning, pr as isReadableBag, pt as interruptWatchListenerCount, q as red, qi as StackTerminationProtectionError, qn as maskSecretsInError, qr as escapeRegExp, qt as requireConfigArray, r as DeployEngine, ra as isTransientServerError, ri as resolveCaptureObservedState, rn as s3BucketWebsiteUrl, rr as buildLockContentionMessage, rt as IAMRoleProvider, s as planRollback, si as resolveUseCdkBootstrapAssets, sn as DiffCalculator, sr as CUSTOM_RESOURCE_RESPONSE_PREFIX, st as wouldReturnToSdkProvider, t as DEFAULT_RESOURCE_TIMEOUT_MS, ta as isRetryableTransientError, ti as resolveApp, tn as s3BucketDualStackDomainName, tr as rebuildClientForBucketRegion, tt as secretSafeKeyDisplay, u as updatePartialMessage, ui as CFN_TEMPLATE_BODY_LIMIT, un as hasReadableOutputs, ur as hasReadableExportSet, ut as maskerOrIdentity, v as keptWholeReasonText, vi as PARTITION_TABLE, vn as malformedResourcePropertiesWarning, vr as stringifyValue, vt as slowCcOperationTimeoutMs, w as ccRoutedFinalSnapshotError, wi as resolveBucketRegion, wn as refuseMalformedOutputsForDestroy, wr as AssetModeResolver, wt as IntrinsicFunctionResolver, x as ATOMIC_FINAL_SNAPSHOT_TYPES, xi as AssemblyReader, xn as producerRecordKey, xr as createAssetRedirectResolver, xt as deleteSkipReason, y as mergeNoChangeOutputs, yi as canonicalizeRegion, yn as malformedResourcesWarning, yr as WorkGraph, yt as UNSPECIFIED_SKIP_REASON, z as isWarmThroughputDecrease, zn as TEMPLATE_SOURCED_RULES, zr as describeDockerFailure, zt as assertRegionMatch } from "./deploy-engine-KnCjibgq.js";
2
- import { C as displaySafe, S as displayIdent, _ as withSkipPrefix, b as STACK_REF_MAX_CODE_POINTS, c as PATTERN_B_NAME_OPTIONS, f as explicitNamePropertyFor, h as getCurrentStackName, i as reserveStdoutForPayload, l as PATTERN_B_NAME_PROPERTIES, m as generateResourceNameWithFallback, n as getLogger, o as runStackBuffered, p as generateResourceName, s as getLiveRenderer, u as PATTERN_B_RESOURCE_TYPES, v as withStackName, w as truncateCodePoints, x as UNRENDERABLE } from "./logger-C17H06QA.js";
1
+ import { $ as secretBearing, $n as scrubResourceRecord, $r as Synthesizer, $t as s3BucketArn, A as extractDeploymentEventError, Ai as setAwsClients, An as repairMalformedResourcesForReadOnly, Ar as isCrossRegionRedirect, At as isImpossibleEmptyStoredAttribute, B as toCfnInteger, Bi as LocalStartServiceError, Bn as TEMPLATE_SOURCED_RULES, Br as describeDockerExecFailure, Bt as coerceCfnBoolean, C as buildFinalSnapshotIdentifier, Ci as AssemblyReader, Cn as refuseMalformedOutputs, Cr as loadPublishableAssetManifest, Ct as isTerminationProtectionPropagationError, D as refusesFinalSnapshot, Di as AwsClients, Dn as refuseMalformedState, Dr as assertAssetBucketRegion, Dt as cfnRefValueFromPhysicalId, E as isFinalSnapshotError, Ei as resolveBucketRegion, En as refuseMalformedResourcesForDestroy, Er as BOOTSTRAP_MARKER_PREFIX, Et as carriesFetchableDynamicReference, F as isStatefulRecreateTargetSync, Fn as DagBuilder, Fr as buildDenyExternalAccessPolicy, Ft as isSettledInstanceState, G as gray, Gi as ProvisioningError, Gn as identityKeyFor, Gr as partitionSensitiveEnv, Gt as readConfigString, H as formatResourceLine, Hi as MalformedProducerRecordRefusalError, Hn as createSecretMasker, Hr as dockerSpawnEnvWithSensitive, Ht as configBooleanRefusal, I as renderStatefulReason, Ii as DeployCancelledError, In as TemplateParser, Ir as describeAwsFailure, It as WAFv2WebACLProvider, J as yellow, Ji as StackHasActiveImportsError, Jn as maskSecretsInError, Jr as runDockerStreaming, Jt as requireConfigObject, K as green, Ki as ResourceTimeoutError, Kn as isSingleDynamicReferenceToken, Kr as redactDockerArgvValues, Kt as replayWarn, L as WARM_THROUGHPUT_MEMBERS, Li as DynamicReferenceRegionAmbiguousError, Ln as STATE_SOURCED_BASELINE_RULES, Lr as safeStringify, Lt as normalizeAwsTagsToCfn, M as planOrphanAdoption, Mi as CdkdError, Mn as findSilentDropProperties, Mr as readBootstrapMarkerBody, Mt as isUnboundTemplateParameter, N as MULTI_REGION_RECREATE_BLOCKED_TYPES, Nn as describeTypeWithThrottleRetry, Nr as validateAssetBucketName, Nt as parameterTypeMayLoseSecretIdentity, O as unsupportedFinalSnapshotError, Oi as getAwsClients, On as repairMalformedOutputsForReadOnly, Or as ensureAssetStorage, Ot as coerceParameterTypedValue, P as isStatefulRecreateTargetForReplace, Pi as CrossAccountSecretRefusalError, Pn as withRetry, Pr as validateContainerRepoName, Pt as refStateLookupFromResource, Q as isExportAliasCollision, Qn as redactSecretsForState, Qr as getDockerImageBySourceHash, Qt as withSharedDrainBudget, R as coerceWarmThroughput$1, Ri as IntrinsicResolutionRefusalError, Rn as STATE_SOURCED_CROSS_GENERATION_RULES, Rr as buildDockerImage, Rt as resolveExplicitPhysicalId, S as PRE_DELETE_SNAPSHOT_TYPES, Si as derivePartitionAndUrlSuffix, Sn as refuseMalformedNestedChildOutputs, Sr as createAssetRedirectResolver, St as disableInstanceApiTermination, T as createPreDeleteFinalSnapshot, Tn as refuseMalformedResourcePropertiesForOrphan, Tr as AssetModeResolver, Tt as carriesDynamicReference, U as bold, Ui as NestedStackChildDirectDestroyError, Un as dynamicReferenceTokens, Ur as formatDockerLoginError, Ut as configIntegerRefusal, V as toFiniteNumber, Vn as carriesSecretMask, Vr as describeDockerFailure, Vt as coerceCfnInteger, W as cyan, Wi as PartialFailureError, Wn as errorCauseChain, Wr as getDockerCmd, Wt as configStringRefusal, X as collectPublishedOutputNames, Xn as recordMaskOnlyValue, Xr as stripControlChars, Xt as classifyReplaySecretRegion, Y as collectDeclaredOutputNames, Yi as StackTerminationProtectionError, Yn as maskSecretsInText, Yr as escapeRegExp, Yt as requireConfigString, Z as exportAliasCollisionScrubWarning, Zn as recoverMaskedOutput, Zr as AssetManifestLoader, Zt as producerRegionsFromState, _ as isSecretBearingReferenceString, _i as CUSTOM_RESOURCE_RESPONSE_OBJECT_DESCRIPTION, _n as malformedRenderedContainersWarning, _r as shouldRetainResource, _t as isWaitAbandonedError, a as DeploymentEventsStore, aa as isTransientServerError, ai as resolveCaptureObservedState, an as applyCallerIdentityCredentials, ar as forceQuitRecoveryClause, at as clearOnUpdateRemoval, b as bindingSkippedOutputs, bi as PARTITION_TABLE, bn as malformedStateRefusalMessage, br as WorkGraph, bt as deleteIndeterminateGuards, c as replayFailedOperations, ca as retryClassificationText, ci as resolveStateBucketWithDefaultAndSource, cn as INTRINSIC_KEYS, cr as CUSTOM_RESOURCE_RESPONSE_PREFIX, ct as createMaskedRetryLogger, d as updatePartialReason, di as warnDeprecatedNoPrefixCliFlag, dn as hasReadableResources, dr as hasReadableExportSet, dt as beginCommandInterruptScope, ea as normalizeAwsError, ei as synthesisStatusMessage, en as s3BucketDomainName, er as LockManager, et as secretBearingStateKeyWarning, f as withResourceDeadline, fi as CFN_TEMPLATE_BODY_LIMIT, fn as malformedExportNamesWarning, fr as importableOutputKeys, ft as endCommandInterruptScope, g as bagHoldsSecretExpression, gi as uploadCfnTemplate, gn as malformedOutputsWarning, gr as orphansCarriedFrom, gt as CloudControlProvider, h as computeImplicitDeleteEdges, hi as findLargeInlineResources, hn as malformedOutputsRefusalMessage, hr as orphansAfterRollback, ht as startInterruptWatch, i as DeploymentEventsReader, ia as isThrottlingError, ii as resolveAutoAssetStorage, in as applyRoleArnIfSet, ir as buildLockContentionMessage, it as collectInlinePolicyNamesManagedBySiblings, j as makeSiblingClaimReader, jn as findActionableSilentDrops, jr as parseBootstrapMarker, jt as isNamelessDynamicReferenceError, k as makeCanonicalizePropertiesFn, ki as resetAwsClients, kn as repairMalformedResourcePropertiesForReadOnly, kr as getBootstrapMarkerKey, kt as getAccountInfo, l as replayRollback, li as resolveUseCdkBootstrapAssets, ln as STATE_RESOURCES_MALFORMED, lr as DEFAULT_STATE_PREFIX, lt as maskDeep, m as IMPLICIT_DELETE_DEPENDENCIES, mi as MIGRATE_TMP_PREFIX, mn as malformedLocalOutputsWarning, mr as isReadableBag, mt as isInterruptedWaitError, n as DEFAULT_RESOURCE_WARN_AFTER_MS, na as isMarkedNonRetryable, ni as getLegacyStateBucketName, nn as s3BucketRegionalDomainName, nr as rebuildClientForBucketRegion, nt as getCurrentResourceSecrets, o as planFailedOps, oa as markNonRetryable, oi as resolveSkipPrefix, on as callerEnvCredentials, or as formatLockExpiry, ot as ProviderRegistry, p as maskingRetryLogger, pi as CFN_TEMPLATE_URL_LIMIT, pn as malformedExportSourceWarning, pr as importableOutputs, pt as interruptWatchListenerCount, q as red, qi as ResourceUpdateNotSupportedError, qn as markSameGenerationBag, qr as runDockerForeground, qt as requireConfigArray, r as DeployEngine, ra as isRetryableTransientError, ri as resolveApp, rn as s3BucketWebsiteUrl, rr as buildForceUnlockCommand, rt as IAMRoleProvider, s as planRollback, sa as markRedactedCause, si as resolveStateBucketWithDefault, sn as DiffCalculator, sr as shellQuote, st as wouldReturnToSdkProvider, t as DEFAULT_RESOURCE_TIMEOUT_MS, ta as withErrorHandling, ti as getDefaultStateBucketName, tn as s3BucketDualStackDomainName, tr as S3StateBackend, tt as secretSafeKeyDisplay, u as updatePartialMessage, ui as stateBucketExistenceConfirmed, un as hasReadableOutputs, ur as exportNamesCarriedFrom, ut as maskerOrIdentity, v as keptWholeReasonText, vi as decodeListingKey, vn as malformedResourcePropertiesWarning, vr as AssetPublisher, vt as slowCcOperationTimeoutMs, w as ccRoutedFinalSnapshotError, wi as processStackMessages, wn as refuseMalformedOutputsForDestroy, wr as rewriteTemplateAssetReferences, wt as IntrinsicFunctionResolver, x as ATOMIC_FINAL_SNAPSHOT_TYPES, xi as canonicalizeRegion, xn as producerRecordKey, xr as buildAssetRedirectMap, xt as deleteSkipReason, y as mergeNoChangeOutputs, yi as expectedOwnerParam, yn as malformedResourcesWarning, yr as stringifyValue, yt as UNSPECIFIED_SKIP_REASON, z as isWarmThroughputDecrease, zi as LocalInvokeBuildError$1, zn as STATE_SOURCED_READBACK_RULES, zr as describeDockerCapturedOutput, zt as assertRegionMatch } from "./deploy-engine-CBzq85r6.js";
2
+ import { C as displaySafe, S as displayIdent, _ as withSkipPrefix, b as STACK_REF_MAX_CODE_POINTS, c as PATTERN_B_NAME_OPTIONS, f as explicitNamePropertyFor, h as getCurrentStackName, i as reserveStdoutForPayload, l as PATTERN_B_NAME_PROPERTIES, m as generateResourceNameWithFallback, n as getLogger, o as runStackBuffered, p as generateResourceName, s as getLiveRenderer, u as PATTERN_B_RESOURCE_TYPES, v as withStackName, w as truncateCodePoints, x as UNRENDERABLE } from "./logger-CkHVgzLx.js";
3
3
  import { n as awsClientDefaults } from "./aws-client-defaults-BoIxyCir.js";
4
- import { t as getCdkdVersion } from "./version-CGcB3KHZ.js";
5
- import { a as renderDisableCommand, i as protectedReplacementAdvice, r as UNNAMEABLE_ID_CLAUSE, t as ASGProvider } from "./asg-provider-B8GAVns4.js";
4
+ import { t as getCdkdVersion } from "./version-DxUVmvM5.js";
5
+ import { a as renderDisableCommand, i as protectedReplacementAdvice, r as UNNAMEABLE_ID_CLAUSE, t as ASGProvider } from "./asg-provider-BOYln2Tw.js";
6
6
  import { AsyncLocalStorage } from "node:async_hooks";
7
7
  import { createHash, randomBytes, randomUUID } from "node:crypto";
8
8
  import { CopyObjectCommand, CreateBucketCommand, DeleteBucketAnalyticsConfigurationCommand, DeleteBucketCommand, DeleteBucketCorsCommand, DeleteBucketEncryptionCommand, DeleteBucketIntelligentTieringConfigurationCommand, DeleteBucketInventoryConfigurationCommand, DeleteBucketLifecycleCommand, DeleteBucketMetricsConfigurationCommand, DeleteBucketOwnershipControlsCommand, DeleteBucketPolicyCommand, DeleteBucketReplicationCommand, DeleteBucketTaggingCommand, DeleteBucketWebsiteCommand, DeleteObjectsCommand, GetBucketAccelerateConfigurationCommand, GetBucketCorsCommand, GetBucketEncryptionCommand, GetBucketLifecycleConfigurationCommand, GetBucketLocationCommand, GetBucketLoggingCommand, GetBucketNotificationConfigurationCommand, GetBucketOwnershipControlsCommand, GetBucketPolicyCommand, GetBucketReplicationCommand, GetBucketTaggingCommand, GetBucketVersioningCommand, GetBucketWebsiteCommand, GetObjectCommand, GetObjectLockConfigurationCommand, GetPublicAccessBlockCommand, HeadBucketCommand, ListBucketAnalyticsConfigurationsCommand, ListBucketIntelligentTieringConfigurationsCommand, ListBucketInventoryConfigurationsCommand, ListBucketMetricsConfigurationsCommand, ListObjectVersionsCommand, ListObjectsV2Command, NoSuchBucket, NotFound, PutBucketAccelerateConfigurationCommand, PutBucketAnalyticsConfigurationCommand, PutBucketCorsCommand, PutBucketEncryptionCommand, PutBucketIntelligentTieringConfigurationCommand, PutBucketInventoryConfigurationCommand, PutBucketLifecycleConfigurationCommand, PutBucketLoggingCommand, PutBucketMetricsConfigurationCommand, PutBucketNotificationConfigurationCommand, PutBucketOwnershipControlsCommand, PutBucketPolicyCommand, PutBucketReplicationCommand, PutBucketTaggingCommand, PutBucketVersioningCommand, PutBucketWebsiteCommand, PutObjectCommand, PutObjectLockConfigurationCommand, PutPublicAccessBlockCommand, S3Client, S3ServiceException } from "@aws-sdk/client-s3";
@@ -4777,7 +4777,7 @@ var IAMManagedPolicyProvider = class {
4777
4777
  await this.iamClient.send(new DeletePolicyCommand({ PolicyArn: policyArn }));
4778
4778
  this.logger.debug(`Cleaned up partially-created managed policy ${logicalId} (${policyArn}) after attachment failure`);
4779
4779
  } catch (cleanupError) {
4780
- this.logger.warn(`Failed to clean up partially-created managed policy ${logicalId} (${policyArn}): ${cleanupError instanceof Error ? cleanupError.message : String(cleanupError)}. Manual deletion may be required: detach principals (aws iam list-entities-for-policy --policy-arn ${policyArn}), delete versions (aws iam list-policy-versions --policy-arn ${policyArn} then aws iam delete-policy-version), then aws iam delete-policy --policy-arn ${policyArn}`);
4780
+ this.logger.warn(`Failed to clean up partially-created managed policy ${logicalId} (${policyArn}): ${describeAwsFailure(cleanupError).detail}. Manual deletion may be required: detach principals (aws iam list-entities-for-policy --policy-arn ${policyArn}), delete versions (aws iam list-policy-versions --policy-arn ${policyArn} then aws iam delete-policy-version), then aws iam delete-policy --policy-arn ${policyArn}`);
4781
4781
  }
4782
4782
  throw innerError;
4783
4783
  }
@@ -4811,8 +4811,8 @@ var IAMManagedPolicyProvider = class {
4811
4811
  this.logger.warn(`Skipped deleting old managed policy ${physicalId} during replacement: ${deleteResult.reason}. The old policy may be orphaned and require manual cleanup.`);
4812
4812
  }
4813
4813
  } catch (error) {
4814
- orphanReason = `old managed policy ${physicalId} could not be deleted: ${String(error)}`;
4815
- this.logger.warn(`Failed to delete old managed policy ${physicalId} during replacement: ${String(error)}. The old policy may be orphaned and require manual cleanup.`);
4814
+ orphanReason = `old managed policy ${physicalId} could not be deleted: ${safeStringify(error)}`;
4815
+ this.logger.warn(`Failed to delete old managed policy ${physicalId} during replacement: ${safeStringify(error)}. The old policy may be orphaned and require manual cleanup.`);
4816
4816
  }
4817
4817
  const base = {
4818
4818
  physicalId: createResult.physicalId,
@@ -5272,7 +5272,7 @@ var IAMInstanceProfileProvider = class {
5272
5272
  await this.iamClient.send(new DeleteInstanceProfileCommand({ InstanceProfileName: instanceProfileName }));
5273
5273
  this.logger.debug(`Cleaned up partially-created IAM instance profile ${logicalId} (${instanceProfileName}) after wiring failure`);
5274
5274
  } catch (cleanupError) {
5275
- this.logger.warn(`Failed to clean up partially-created IAM instance profile ${logicalId} (${instanceProfileName}): ${cleanupError instanceof Error ? cleanupError.message : String(cleanupError)}. Manual deletion may be required before the next deploy: remove every role (aws iam remove-role-from-instance-profile --instance-profile-name ${instanceProfileName} --role-name <name>) then aws iam delete-instance-profile --instance-profile-name ${instanceProfileName}`);
5275
+ this.logger.warn(`Failed to clean up partially-created IAM instance profile ${logicalId} (${instanceProfileName}): ${describeAwsFailure(cleanupError).detail}. Manual deletion may be required before the next deploy: remove every role (aws iam remove-role-from-instance-profile --instance-profile-name ${instanceProfileName} --role-name <name>) then aws iam delete-instance-profile --instance-profile-name ${instanceProfileName}`);
5276
5276
  }
5277
5277
  throw innerError;
5278
5278
  }
@@ -5548,7 +5548,7 @@ var IAMAccessKeyProvider = class {
5548
5548
  AccessKeyId: accessKeyId
5549
5549
  }));
5550
5550
  } catch (cleanupError) {
5551
- this.logger.warn(`Failed to clean up IAM access key ${logicalId} (${accessKeyId}) minted by a partial CreateAccessKey response: ${cleanupError instanceof Error ? cleanupError.message : String(cleanupError)}. Manual deletion may be required: aws iam delete-access-key --user-name ${userName} --access-key-id ${accessKeyId}`);
5551
+ this.logger.warn(`Failed to clean up IAM access key ${logicalId} (${accessKeyId}) minted by a partial CreateAccessKey response: ${describeAwsFailure(cleanupError).detail}. Manual deletion may be required: aws iam delete-access-key --user-name ${userName} --access-key-id ${accessKeyId}`);
5552
5552
  }
5553
5553
  throw new Error("CreateAccessKey returned no AccessKeyId/SecretAccessKey");
5554
5554
  }
@@ -5566,7 +5566,7 @@ var IAMAccessKeyProvider = class {
5566
5566
  }));
5567
5567
  this.logger.debug(`Cleaned up partially-created IAM access key ${logicalId} (${accessKeyId}) after status wiring failure`);
5568
5568
  } catch (cleanupError) {
5569
- this.logger.warn(`Failed to clean up partially-created IAM access key ${logicalId} (${accessKeyId}): ${cleanupError instanceof Error ? cleanupError.message : String(cleanupError)}. Manual deletion may be required before the next deploy: aws iam delete-access-key --user-name ${userName} --access-key-id ${accessKeyId}`);
5569
+ this.logger.warn(`Failed to clean up partially-created IAM access key ${logicalId} (${accessKeyId}): ${describeAwsFailure(cleanupError).detail}. Manual deletion may be required before the next deploy: aws iam delete-access-key --user-name ${userName} --access-key-id ${accessKeyId}`);
5570
5570
  }
5571
5571
  throw innerError;
5572
5572
  }
@@ -5671,7 +5671,7 @@ var IAMAccessKeyProvider = class {
5671
5671
  AccessKeyId: accessKeyId
5672
5672
  }));
5673
5673
  } catch (error) {
5674
- this.logger.warn(`Failed to delete the orphaned IAM access key ${accessKeyId} for user ${userName}: ${error instanceof Error ? error.message : String(error)}. Manual deletion may be required: aws iam delete-access-key --user-name ${userName} --access-key-id ${accessKeyId}`);
5674
+ this.logger.warn(`Failed to delete the orphaned IAM access key ${accessKeyId} for user ${userName}: ${describeAwsFailure(error).detail}. Manual deletion may be required: aws iam delete-access-key --user-name ${userName} --access-key-id ${accessKeyId}`);
5675
5675
  }
5676
5676
  }
5677
5677
  }
@@ -5703,7 +5703,7 @@ var IAMAccessKeyProvider = class {
5703
5703
  marker = page.IsTruncated ? page.Marker : void 0;
5704
5704
  } while (marker);
5705
5705
  } catch (error) {
5706
- this.logger.warn(`Could not list existing access keys for user ${userName} while creating ${logicalId}: ${error instanceof Error ? error.message : String(error)}. Orphan detection is DISABLED for this create, so a retried attempt may leave an unusable but ACTIVE access key on the user. Grant iam:ListAccessKeys, or check the user's keys after the deploy: aws iam list-access-keys --user-name ${userName}`);
5706
+ this.logger.warn(`Could not list existing access keys for user ${userName} while creating ${logicalId}: ${describeAwsFailure(error).detail}. Orphan detection is DISABLED for this create, so a retried attempt may leave an unusable but ACTIVE access key on the user. Grant iam:ListAccessKeys, or check the user's keys after the deploy: aws iam list-access-keys --user-name ${userName}`);
5707
5707
  return;
5708
5708
  }
5709
5709
  return keys;
@@ -6015,7 +6015,7 @@ var IAMUserGroupProvider = class {
6015
6015
  await this.iamClient.send(new DeleteUserCommand({ UserName: userName }));
6016
6016
  this.logger.debug(`Cleaned up partially-created IAM user ${logicalId} (${userName}) after wiring failure`);
6017
6017
  } catch (cleanupError) {
6018
- this.logger.warn(`Failed to clean up partially-created IAM user ${logicalId} (${userName}): ${cleanupError instanceof Error ? cleanupError.message : String(cleanupError)}. Manual deletion may be required before the next deploy: remove from groups, detach managed policies, delete inline policies, delete login profile (aws iam delete-login-profile --user-name ${userName}), remove permissions boundary (aws iam delete-user-permissions-boundary --user-name ${userName}), then aws iam delete-user --user-name ${userName}`);
6018
+ this.logger.warn(`Failed to clean up partially-created IAM user ${logicalId} (${userName}): ${describeAwsFailure(cleanupError).detail}. Manual deletion may be required before the next deploy: remove from groups, detach managed policies, delete inline policies, delete login profile (aws iam delete-login-profile --user-name ${userName}), remove permissions boundary (aws iam delete-user-permissions-boundary --user-name ${userName}), then aws iam delete-user --user-name ${userName}`);
6019
6019
  }
6020
6020
  throw innerError;
6021
6021
  }
@@ -6313,7 +6313,7 @@ var IAMUserGroupProvider = class {
6313
6313
  await this.iamClient.send(new DeleteGroupCommand({ GroupName: groupName }));
6314
6314
  this.logger.debug(`Cleaned up partially-created IAM group ${logicalId} (${groupName}) after wiring failure`);
6315
6315
  } catch (cleanupError) {
6316
- this.logger.warn(`Failed to clean up partially-created IAM group ${logicalId} (${groupName}): ${cleanupError instanceof Error ? cleanupError.message : String(cleanupError)}. Manual deletion may be required before the next deploy: detach managed policies + delete inline policies, then aws iam delete-group --group-name ${groupName}`);
6316
+ this.logger.warn(`Failed to clean up partially-created IAM group ${logicalId} (${groupName}): ${describeAwsFailure(cleanupError).detail}. Manual deletion may be required before the next deploy: detach managed policies + delete inline policies, then aws iam delete-group --group-name ${groupName}`);
6317
6317
  }
6318
6318
  throw innerError;
6319
6319
  }
@@ -10059,7 +10059,7 @@ var S3BucketProvider = class S3BucketProvider {
10059
10059
  }
10060
10060
  return {
10061
10061
  kind: "indeterminate",
10062
- reason: probeError instanceof Error ? probeError.message : String(probeError),
10062
+ reason: describeAwsFailure(probeError).detail,
10063
10063
  errorName: probeError instanceof Error ? probeError.name : typeof probeError
10064
10064
  };
10065
10065
  }
@@ -10223,7 +10223,7 @@ var S3BucketProvider = class S3BucketProvider {
10223
10223
  await this.s3Client.send(new DeleteBucketCommand({ Bucket: bucketName }));
10224
10224
  this.logger.debug(`Cleaned up partially-created S3 bucket ${logicalId} (${bucketName}) after wiring failure`);
10225
10225
  } catch (cleanupError) {
10226
- this.logger.debug(`DeleteBucket cleanup failed for S3 bucket ${logicalId} (${bucketName}): ${cleanupError instanceof Error ? cleanupError.message : String(cleanupError)}`);
10226
+ this.logger.debug(`DeleteBucket cleanup failed for S3 bucket ${logicalId} (${bucketName}): ${describeAwsFailure(cleanupError).detail}`);
10227
10227
  const maskSecrets = maskerOrIdentity(context?.maskSecrets);
10228
10228
  this.logger.warn(maskSecrets(`Failed to clean up partially-created S3 bucket ${logicalId} (${bucketName}) (${cleanupError instanceof Error ? cleanupError.name : typeof cleanupError}). Re-run with --verbose for AWS's own message. ` + manualBucketDeletionClause(bucketName, maskSecrets)));
10229
10229
  }
@@ -11037,7 +11037,7 @@ var S3BucketProvider = class S3BucketProvider {
11037
11037
  this.logger.debug(`Successfully deleted S3 bucket ${logicalId}`);
11038
11038
  return;
11039
11039
  } catch (error) {
11040
- const msg = error instanceof Error ? error.message : String(error);
11040
+ const msg = describeAwsFailure(error).detail;
11041
11041
  if (msg.includes("not empty") || msg.includes("BucketNotEmpty")) {
11042
11042
  if (!allowAutoEmpty) throw new Error(`bucket ${bucketName} is not empty. Matching CloudFormation, cdkd does not delete a non-empty bucket unless it opted into automatic emptying (CDK's autoDeleteObjects: true, i.e. the '${S3_AUTO_DELETE_OBJECTS_TAG}' tag). Either empty the bucket first (delete all objects — and for versioned buckets all object versions and delete markers), or redeploy with autoDeleteObjects: true and destroy again.`);
11043
11043
  this.logger.info(`Bucket ${bucketName} not empty (attempt ${attempt}/${maxAttempts}), emptying (auto-delete opt-in present)...`);
@@ -11361,7 +11361,7 @@ var S3BucketPolicyProvider = class {
11361
11361
  try {
11362
11362
  canonical = (await getAwsClients().cloudFront.send(new GetCloudFrontOriginAccessIdentityCommand({ Id: oaiId }))).CloudFrontOriginAccessIdentity?.S3CanonicalUserId ?? null;
11363
11363
  } catch (err) {
11364
- this.logger.debug(`Could not resolve CloudFront OAI ${oaiId} canonical user id for bucket-policy drift normalization: ${err instanceof Error ? err.message : String(err)} — leaving the principal unchanged.`);
11364
+ this.logger.debug(`Could not resolve CloudFront OAI ${oaiId} canonical user id for bucket-policy drift normalization: ${describeAwsFailure(err).detail} — leaving the principal unchanged.`);
11365
11365
  canonical = null;
11366
11366
  }
11367
11367
  oaiCanonicalUserIdCache.set(oaiId, canonical);
@@ -12244,7 +12244,7 @@ var SNSTopicProvider = class {
12244
12244
  await this.snsClient.send(new DeleteTopicCommand({ TopicArn: topicArn }));
12245
12245
  this.logger.debug(`Cleaned up partially-created SNS topic ${logicalId} (${topicArn}) after wiring failure`);
12246
12246
  } catch (cleanupError) {
12247
- warn(`Failed to clean up partially-created SNS topic ${logicalId} (${topicArn}): ${cleanupError instanceof Error ? cleanupError.message : String(cleanupError)}. Manual deletion may be required before the next deploy: aws sns delete-topic --topic-arn ${topicArn}`);
12247
+ warn(`Failed to clean up partially-created SNS topic ${logicalId} (${topicArn}): ${describeAwsFailure(cleanupError).detail}. Manual deletion may be required before the next deploy: aws sns delete-topic --topic-arn ${topicArn}`);
12248
12248
  }
12249
12249
  throw innerError;
12250
12250
  }
@@ -13077,7 +13077,7 @@ var SNSSubscriptionProvider = class {
13077
13077
  deleteResult = await this.delete(logicalId, physicalId, resourceType);
13078
13078
  } catch (error) {
13079
13079
  deleteThrew = true;
13080
- this.logger.warn(`Failed to delete old subscription ${physicalId} during update: ${String(error)}`);
13080
+ this.logger.warn(`Failed to delete old subscription ${physicalId} during update: ${safeStringify(error)}`);
13081
13081
  }
13082
13082
  const notDeletedReason = deleteThrew ? SNS_SUBSCRIPTION_DELETE_THREW_REASON : deleteResult?.outcome === "skipped" ? deleteResult.reason : void 0;
13083
13083
  if (notDeletedReason !== void 0) {
@@ -13657,7 +13657,7 @@ var LambdaFunctionProvider = class {
13657
13657
  try {
13658
13658
  await send();
13659
13659
  } catch (error) {
13660
- const message = error instanceof Error ? error.message : String(error);
13660
+ const message = describeAwsFailure(error).detail;
13661
13661
  this.logger.warn(`${ctx.apiName} failed for ${ctx.logicalId}: ${message} — deleting partially-created function to maintain atomicity`);
13662
13662
  let cleanupFailure;
13663
13663
  for (let attempt = 0; attempt < LAMBDA_CLEANUP_DELETE_MAX_ATTEMPTS; attempt++) try {
@@ -13665,7 +13665,7 @@ var LambdaFunctionProvider = class {
13665
13665
  cleanupFailure = void 0;
13666
13666
  break;
13667
13667
  } catch (deleteError) {
13668
- const deleteMessage = deleteError instanceof Error ? deleteError.message : String(deleteError);
13668
+ const deleteMessage = describeAwsFailure(deleteError).detail;
13669
13669
  cleanupFailure = deleteMessage;
13670
13670
  if (!/currently in the following state|ResourceConflict/i.test(deleteMessage)) break;
13671
13671
  if (attempt < 2) await new Promise((resolve) => setTimeout(resolve, this.cleanupDeleteRetryDelayMs * (attempt + 1)));
@@ -13858,7 +13858,7 @@ var LambdaFunctionProvider = class {
13858
13858
  assertRegionMatch(clientRegion, context?.expectedRegion, resourceType, logicalId, physicalId);
13859
13859
  return;
13860
13860
  }
13861
- this.logger.warn(`Pre-delete VPC detach failed for ${physicalId}: ${error instanceof Error ? error.message : String(error)} — continuing with delete`);
13861
+ this.logger.warn(`Pre-delete VPC detach failed for ${physicalId}: ${describeAwsFailure(error).detail} — continuing with delete`);
13862
13862
  }
13863
13863
  await this.waitForLambdaUpdateCompleted(physicalId);
13864
13864
  }
@@ -14060,7 +14060,7 @@ var LambdaFunctionProvider = class {
14060
14060
  status = (await this.lambdaClient.send(new GetFunctionCommand({ FunctionName: functionName }))).Configuration?.LastUpdateStatus;
14061
14061
  } catch (error) {
14062
14062
  if (error instanceof ResourceNotFoundException) return;
14063
- this.logger.debug(`GetFunction failed while waiting for ${functionName} update: ${error instanceof Error ? error.message : String(error)}`);
14063
+ this.logger.debug(`GetFunction failed while waiting for ${functionName} update: ${describeAwsFailure(error).detail}`);
14064
14064
  }
14065
14065
  if (status && status !== "InProgress") {
14066
14066
  this.logger.debug(`Lambda ${functionName} update completed (LastUpdateStatus=${status}) after ${Date.now() - start}ms`);
@@ -14084,7 +14084,7 @@ var LambdaFunctionProvider = class {
14084
14084
  try {
14085
14085
  enis = await this.listLambdaEnis(functionName);
14086
14086
  } catch (error) {
14087
- this.logger.warn(`DescribeNetworkInterfaces failed for ${functionName}: ${error instanceof Error ? error.message : String(error)} — downstream Subnet/SG deletion will fall back to its own ENI cleanup`);
14087
+ this.logger.warn(`DescribeNetworkInterfaces failed for ${functionName}: ${describeAwsFailure(error).detail} — downstream Subnet/SG deletion will fall back to its own ENI cleanup`);
14088
14088
  return;
14089
14089
  }
14090
14090
  if (enis.length === 0) {
@@ -14100,7 +14100,7 @@ var LambdaFunctionProvider = class {
14100
14100
  this.logger.debug(`Deleted Lambda ENI ${eniId} for ${functionName}`);
14101
14101
  return;
14102
14102
  } catch (error) {
14103
- const msg = error instanceof Error ? error.message : String(error);
14103
+ const msg = describeAwsFailure(error).detail;
14104
14104
  if (msg.includes("InvalidNetworkInterfaceID.NotFound") || msg.includes("does not exist")) return;
14105
14105
  const elapsed = Date.now() - start;
14106
14106
  if (elapsed >= this.eniDeleteRetryBudgetMs) {
@@ -14348,13 +14348,13 @@ var LambdaFunctionProvider = class {
14348
14348
  const rlResp = await this.lambdaClient.send(new GetFunctionRecursionConfigCommand({ FunctionName: physicalId }));
14349
14349
  if (rlResp.RecursiveLoop !== void 0) result["RecursiveLoop"] = rlResp.RecursiveLoop;
14350
14350
  } catch (rlErr) {
14351
- if (!(rlErr instanceof ResourceNotFoundException)) this.logger.debug(`GetFunctionRecursionConfig failed for ${physicalId}: ${rlErr instanceof Error ? rlErr.message : String(rlErr)}`);
14351
+ if (!(rlErr instanceof ResourceNotFoundException)) this.logger.debug(`GetFunctionRecursionConfig failed for ${physicalId}: ${describeAwsFailure(rlErr).detail}`);
14352
14352
  }
14353
14353
  try {
14354
14354
  const pcResp = await this.lambdaClient.send(new GetFunctionConcurrencyCommand({ FunctionName: physicalId }));
14355
14355
  if (pcResp.ReservedConcurrentExecutions !== void 0) result["ReservedConcurrentExecutions"] = pcResp.ReservedConcurrentExecutions;
14356
14356
  } catch (pcErr) {
14357
- if (!(pcErr instanceof ResourceNotFoundException)) this.logger.debug(`GetFunctionConcurrency failed for ${physicalId}: ${pcErr instanceof Error ? pcErr.message : String(pcErr)}`);
14357
+ if (!(pcErr instanceof ResourceNotFoundException)) this.logger.debug(`GetFunctionConcurrency failed for ${physicalId}: ${describeAwsFailure(pcErr).detail}`);
14358
14358
  }
14359
14359
  if (cfg.PackageType !== "Image") {
14360
14360
  try {
@@ -14365,13 +14365,13 @@ var LambdaFunctionProvider = class {
14365
14365
  result["RuntimeManagementConfig"] = rm;
14366
14366
  }
14367
14367
  } catch (rmErr) {
14368
- if (!(rmErr instanceof ResourceNotFoundException)) this.logger.warn(`GetRuntimeManagementConfig failed for ${physicalId} — RuntimeManagementConfig omitted from the drift snapshot (may surface as a false removal): ${rmErr instanceof Error ? rmErr.message : String(rmErr)}`);
14368
+ if (!(rmErr instanceof ResourceNotFoundException)) this.logger.warn(`GetRuntimeManagementConfig failed for ${physicalId} — RuntimeManagementConfig omitted from the drift snapshot (may surface as a false removal): ${describeAwsFailure(rmErr).detail}`);
14369
14369
  }
14370
14370
  try {
14371
14371
  const csResp = await this.lambdaClient.send(new GetFunctionCodeSigningConfigCommand({ FunctionName: physicalId }));
14372
14372
  if (csResp.CodeSigningConfigArn !== void 0) result["CodeSigningConfigArn"] = csResp.CodeSigningConfigArn;
14373
14373
  } catch (csErr) {
14374
- if (!(csErr instanceof ResourceNotFoundException)) this.logger.warn(`GetFunctionCodeSigningConfig failed for ${physicalId} — CodeSigningConfigArn omitted from the drift snapshot (may surface as a false removal): ${csErr instanceof Error ? csErr.message : String(csErr)}`);
14374
+ if (!(csErr instanceof ResourceNotFoundException)) this.logger.warn(`GetFunctionCodeSigningConfig failed for ${physicalId} — CodeSigningConfigArn omitted from the drift snapshot (may surface as a false removal): ${describeAwsFailure(csErr).detail}`);
14375
14375
  }
14376
14376
  }
14377
14377
  return result;
@@ -16784,7 +16784,7 @@ async function waitForIndexesSettled(opts) {
16784
16784
  try {
16785
16785
  if (!hasTransitionalIndex((await describeTable()).Table?.GlobalSecondaryIndexes ?? [])) return;
16786
16786
  } catch (err) {
16787
- const message = err instanceof Error ? err.message : String(err);
16787
+ const message = describeAwsFailure(err).detail;
16788
16788
  if (isThrottlingError(err)) {
16789
16789
  logger.debug(`DescribeTable throttled while waiting for indexes on ${tableName} (attempt ${attempt}/${maxAttempts}); still waiting: ${message}`);
16790
16790
  await new Promise((resolve) => setTimeout(resolve, INDEX_SETTLE_POLL_INTERVAL_MS));
@@ -17603,7 +17603,7 @@ async function compensateRemovedDeletionProtection(opts) {
17603
17603
  opts.logger.warn(`DynamoDB ${opts.typeLabel} ${opts.logicalId}: the delete failed after --remove-protection had turned DeletionProtectionEnabled off, so it was re-enabled on ${opts.physicalId}. The delete failure below is the outcome.`);
17604
17604
  return "restored";
17605
17605
  } catch (reEnableError) {
17606
- const detail = reEnableError instanceof Error ? reEnableError.message : String(reEnableError);
17606
+ const detail = describeAwsFailure(reEnableError).detail;
17607
17607
  if (isResourceNotFoundError(reEnableError)) {
17608
17608
  const regionArg = opts.region ? ` --region ${opts.region}` : "";
17609
17609
  opts.logger.warn(`DynamoDB ${opts.typeLabel} ${opts.logicalId}: could not re-enable DeletionProtectionEnabled on ${opts.physicalId} after the delete failed — DynamoDB answered ResourceNotFound. That most commonly means the table is gone or its status is not ACTIVE, and it can also mean the table is not in this region or account. If it still exists, its deletion protection is OFF. Check with: aws dynamodb describe-table --table-name ${opts.physicalId}${regionArg} and if it is there, restore it with: aws dynamodb update-table --table-name ${opts.physicalId}${regionArg} --deletion-protection-enabled. (${detail})`);
@@ -18455,7 +18455,7 @@ var DynamoDBTableProvider = class {
18455
18455
  await this.dynamoDBClient.send(new DeleteTableCommand({ TableName: tableName }));
18456
18456
  debug(`Rolled back partially-created DynamoDB table ${tableName}`);
18457
18457
  } catch (cleanupError) {
18458
- warn(`Failed to roll back partially-created DynamoDB table ${tableName}: ${cleanupError instanceof Error ? cleanupError.message : String(cleanupError)}`);
18458
+ warn(`Failed to roll back partially-created DynamoDB table ${tableName}: ${describeAwsFailure(cleanupError).detail}`);
18459
18459
  }
18460
18460
  if (error instanceof ProvisioningError) throw error;
18461
18461
  const cause = error instanceof Error ? error : void 0;
@@ -18732,7 +18732,7 @@ var DynamoDBTableProvider = class {
18732
18732
  try {
18733
18733
  observedProtectionOn = (await this.dynamoDBClient.send(new DescribeTableCommand({ TableName: physicalId }))).Table?.DeletionProtectionEnabled === true;
18734
18734
  } catch (observeError) {
18735
- this.logger.debug(`Could not read DeletionProtectionEnabled on ${physicalId} before disabling it: ${observeError instanceof Error ? observeError.message : String(observeError)}`);
18735
+ this.logger.debug(`Could not read DeletionProtectionEnabled on ${physicalId} before disabling it: ${describeAwsFailure(observeError).detail}`);
18736
18736
  }
18737
18737
  await this.dynamoDBClient.send(new UpdateTableCommand({
18738
18738
  TableName: physicalId,
@@ -18743,10 +18743,10 @@ var DynamoDBTableProvider = class {
18743
18743
  try {
18744
18744
  await this.waitForTableActiveAfterUpdate(physicalId, 60, budget);
18745
18745
  } catch (waitErr) {
18746
- this.logger.debug(`Could not wait for table ${physicalId} ACTIVE after disabling protection: ${waitErr instanceof Error ? waitErr.message : String(waitErr)}`);
18746
+ this.logger.debug(`Could not wait for table ${physicalId} ACTIVE after disabling protection: ${describeAwsFailure(waitErr).detail}`);
18747
18747
  }
18748
18748
  } catch (flipError) {
18749
- if (!(flipError instanceof ResourceNotFoundException$1)) this.logger.debug(`Could not disable DeletionProtectionEnabled on ${physicalId}: ${flipError instanceof Error ? flipError.message : String(flipError)}`);
18749
+ if (!(flipError instanceof ResourceNotFoundException$1)) this.logger.debug(`Could not disable DeletionProtectionEnabled on ${physicalId}: ${describeAwsFailure(flipError).detail}`);
18750
18750
  }
18751
18751
  try {
18752
18752
  const reArmPolls = () => {
@@ -18883,7 +18883,7 @@ var DynamoDBTableProvider = class {
18883
18883
  for (let attempt = 1;; attempt++) try {
18884
18884
  return await op();
18885
18885
  } catch (error) {
18886
- const msg = error instanceof Error ? error.message : String(error);
18886
+ const msg = describeAwsFailure(error).detail;
18887
18887
  const name = error instanceof Error ? error.name : "";
18888
18888
  if (!(/being enabled|being updated|please retry later|backups are being/i.test(msg) || name === "ResourceInUseException" || name === "LimitExceededException") || attempt >= maxAttempts) throw error;
18889
18889
  this.logger.debug(`Transient error on "${label}" (attempt ${attempt}/${maxAttempts}): ${msg} — retrying in ${delayMs}ms`);
@@ -19959,7 +19959,7 @@ var DynamoDBTableProvider = class {
19959
19959
  result["PointInTimeRecoverySpecification"] = pitr;
19960
19960
  }
19961
19961
  } catch (err) {
19962
- this.logger.debug(`Could not read PointInTimeRecovery for ${physicalId}: ${err instanceof Error ? err.message : String(err)}`);
19962
+ this.logger.debug(`Could not read PointInTimeRecovery for ${physicalId}: ${describeAwsFailure(err).detail}`);
19963
19963
  }
19964
19964
  try {
19965
19965
  const ttlDesc = (await this.dynamoDBClient.send(new DescribeTimeToLiveCommand({ TableName: physicalId }))).TimeToLiveDescription;
@@ -19968,7 +19968,7 @@ var DynamoDBTableProvider = class {
19968
19968
  Enabled: true
19969
19969
  };
19970
19970
  } catch (err) {
19971
- this.logger.debug(`Could not read TimeToLive for ${physicalId}: ${err instanceof Error ? err.message : String(err)}`);
19971
+ this.logger.debug(`Could not read TimeToLive for ${physicalId}: ${describeAwsFailure(err).detail}`);
19972
19972
  }
19973
19973
  if (table.TableArn) try {
19974
19974
  const rpResp = await this.dynamoDBClient.send(new GetResourcePolicyCommand({ ResourceArn: table.TableArn }));
@@ -19980,7 +19980,7 @@ var DynamoDBTableProvider = class {
19980
19980
  result["ResourcePolicy"] = { PolicyDocument: doc };
19981
19981
  }
19982
19982
  } catch (err) {
19983
- if (!(err instanceof ResourceNotFoundException$1)) this.logger.debug(`Could not read ResourcePolicy for ${physicalId}: ${err instanceof Error ? err.message : String(err)}`);
19983
+ if (!(err instanceof ResourceNotFoundException$1)) this.logger.debug(`Could not read ResourcePolicy for ${physicalId}: ${describeAwsFailure(err).detail}`);
19984
19984
  }
19985
19985
  try {
19986
19986
  const active = ((await this.dynamoDBClient.send(new DescribeKinesisStreamingDestinationCommand({ TableName: physicalId }))).KinesisDataStreamDestinations ?? []).find((d) => d.DestinationStatus === "ACTIVE" || d.DestinationStatus === "ENABLING");
@@ -19990,7 +19990,7 @@ var DynamoDBTableProvider = class {
19990
19990
  result["KinesisStreamSpecification"] = kspec;
19991
19991
  }
19992
19992
  } catch (err) {
19993
- this.logger.debug(`Could not read KinesisStreamingDestination for ${physicalId}: ${err instanceof Error ? err.message : String(err)}`);
19993
+ this.logger.debug(`Could not read KinesisStreamingDestination for ${physicalId}: ${describeAwsFailure(err).detail}`);
19994
19994
  }
19995
19995
  try {
19996
19996
  const ciResp = await this.dynamoDBClient.send(new DescribeContributorInsightsCommand({ TableName: physicalId }));
@@ -20001,7 +20001,7 @@ var DynamoDBTableProvider = class {
20001
20001
  result["ContributorInsightsSpecification"] = cspec;
20002
20002
  }
20003
20003
  } catch (err) {
20004
- this.logger.debug(`Could not read ContributorInsights for ${physicalId}: ${err instanceof Error ? err.message : String(err)}`);
20004
+ this.logger.debug(`Could not read ContributorInsights for ${physicalId}: ${describeAwsFailure(err).detail}`);
20005
20005
  }
20006
20006
  return result;
20007
20007
  } catch (err) {
@@ -20500,7 +20500,7 @@ var DynamoDBGlobalTableProvider = class {
20500
20500
  if (billingMode === "PROVISIONED") try {
20501
20501
  await this.reconcileAutoScalingTargets(tableName, [], collectAutoScalingTargets(properties, currentRegion), currentRegion, void 0, maskSecrets);
20502
20502
  } catch (autoScalingErr) {
20503
- warn(`Auto-scaling registration failed for ${tableName}: ${autoScalingErr instanceof Error ? autoScalingErr.message : String(autoScalingErr)}. The table was created successfully; re-run the deploy to register the scaling targets.`);
20503
+ warn(`Auto-scaling registration failed for ${tableName}: ${describeAwsFailure(autoScalingErr).detail}. The table was created successfully; re-run the deploy to register the scaling targets.`);
20504
20504
  }
20505
20505
  this.logger.debug(`Successfully created DynamoDB GlobalTable ${logicalId}: ${tableName}`);
20506
20506
  return {
@@ -20527,12 +20527,14 @@ var DynamoDBGlobalTableProvider = class {
20527
20527
  }));
20528
20528
  await this.waitForReplicaGone(tableName, region, logicalId);
20529
20529
  } catch (replicaCleanupErr) {
20530
- warn(`Partial-create cleanup: failed to drop replica ${region} on ${tableName}: ${replicaCleanupErr instanceof Error ? replicaCleanupErr.message : String(replicaCleanupErr)}. Run: aws dynamodb update-table --table-name ${tableName} --replica-updates 'Delete={RegionName=${region}}' --region ${currentRegion}`);
20530
+ const msg = describeAwsFailure(replicaCleanupErr).detail;
20531
+ warn(`Partial-create cleanup: failed to drop replica ${region} on ${tableName}: ${msg}. Run: aws dynamodb update-table --table-name ${tableName} --replica-updates 'Delete={RegionName=${region}}' --region ${currentRegion}`);
20531
20532
  }
20532
20533
  }
20533
20534
  await this.dynamoDBClient.send(new DeleteTableCommand({ TableName: tableName }));
20534
20535
  } catch (cleanupErr) {
20535
- warn(`Partial-create cleanup failed for ${tableName}: ${cleanupErr instanceof Error ? cleanupErr.message : String(cleanupErr)}. Run: aws dynamodb delete-table --table-name ${tableName} to remove the orphaned AWS-side table.`);
20536
+ const cleanupMsg = describeAwsFailure(cleanupErr).detail;
20537
+ warn(`Partial-create cleanup failed for ${tableName}: ${cleanupMsg}. Run: aws dynamodb delete-table --table-name ${tableName} to remove the orphaned AWS-side table.`);
20536
20538
  }
20537
20539
  const cause = wiringError instanceof Error ? wiringError : void 0;
20538
20540
  throw new ProvisioningError(`Failed to create DynamoDB GlobalTable ${logicalId}: ${wiringError instanceof Error ? wiringError.message : String(wiringError)}`, resourceType, logicalId, tableName, cause);
@@ -21149,7 +21151,7 @@ var DynamoDBGlobalTableProvider = class {
21149
21151
  const regionalClient = this.getRegionalClient(region);
21150
21152
  await this.applyTagDiffOnClient(regionalClient, replicaArn, oldTags, newTags);
21151
21153
  } catch (tagErr) {
21152
- warn(`Could not apply Tags diff to cross-region replica ${region} of ${physicalIdForLogs}: ${tagErr instanceof Error ? tagErr.message : String(tagErr)}. The replica's Tags state will surface as drift until the next successful deploy.`);
21154
+ warn(`Could not apply Tags diff to cross-region replica ${region} of ${physicalIdForLogs}: ${describeAwsFailure(tagErr).detail}. The replica's Tags state will surface as drift until the next successful deploy.`);
21153
21155
  }
21154
21156
  }
21155
21157
  /**
@@ -21261,7 +21263,7 @@ var DynamoDBGlobalTableProvider = class {
21261
21263
  });
21262
21264
  } catch (err) {
21263
21265
  if (isInterruptedWaitError(err)) throw err;
21264
- warn(`Could not register auto-scaling target on ${tableName} (${dimension}): ${err instanceof Error ? err.message : String(err)}. Run: aws application-autoscaling register-scalable-target --service-namespace dynamodb --resource-id ${resourceId} --scalable-dimension ${dimension} --min-capacity ${minCapacity} --max-capacity ${maxCapacity}`);
21266
+ warn(`Could not register auto-scaling target on ${tableName} (${dimension}): ${describeAwsFailure(err).detail}. Run: aws application-autoscaling register-scalable-target --service-namespace dynamodb --resource-id ${resourceId} --scalable-dimension ${dimension} --min-capacity ${minCapacity} --max-capacity ${maxCapacity}`);
21265
21267
  return;
21266
21268
  }
21267
21269
  const tttCfg = newSettings["TargetTrackingScalingPolicyConfiguration"] ?? {};
@@ -21303,7 +21305,7 @@ var DynamoDBGlobalTableProvider = class {
21303
21305
  this.logger.debug(`Upserted auto-scaling policy ${policyName} on ${tableName} (${dimension})`);
21304
21306
  } catch (err) {
21305
21307
  if (isInterruptedWaitError(err)) throw err;
21306
- warn(`Could not put auto-scaling policy on ${tableName} (${dimension}): ${err instanceof Error ? err.message : String(err)}. Run: aws application-autoscaling put-scaling-policy --policy-name ${policyName} --service-namespace dynamodb --resource-id ${resourceId} --scalable-dimension ${dimension} --policy-type TargetTrackingScaling`);
21308
+ warn(`Could not put auto-scaling policy on ${tableName} (${dimension}): ${describeAwsFailure(err).detail}. Run: aws application-autoscaling put-scaling-policy --policy-name ${policyName} --service-namespace dynamodb --resource-id ${resourceId} --scalable-dimension ${dimension} --policy-type TargetTrackingScaling`);
21307
21309
  }
21308
21310
  return;
21309
21311
  }
@@ -21328,7 +21330,7 @@ var DynamoDBGlobalTableProvider = class {
21328
21330
  });
21329
21331
  } catch (err) {
21330
21332
  if (isInterruptedWaitError(err)) throw err;
21331
- if (!isObjectNotFound(err)) warn(`Could not delete auto-scaling policy on ${tableName} (${dimension}): ${err instanceof Error ? err.message : String(err)}. Run: aws application-autoscaling delete-scaling-policy --policy-name ${policyName} --service-namespace dynamodb --resource-id ${resourceId} --scalable-dimension ${dimension}`);
21333
+ if (!isObjectNotFound(err)) warn(`Could not delete auto-scaling policy on ${tableName} (${dimension}): ${describeAwsFailure(err).detail}. Run: aws application-autoscaling delete-scaling-policy --policy-name ${policyName} --service-namespace dynamodb --resource-id ${resourceId} --scalable-dimension ${dimension}`);
21332
21334
  }
21333
21335
  try {
21334
21336
  await withRetry(() => asClient.send(new DeregisterScalableTargetCommand({
@@ -21345,7 +21347,7 @@ var DynamoDBGlobalTableProvider = class {
21345
21347
  this.logger.debug(`Deregistered auto-scaling target ${resourceId} (${dimension})`);
21346
21348
  } catch (err) {
21347
21349
  if (isInterruptedWaitError(err)) throw err;
21348
- if (!isObjectNotFound(err)) warn(`Could not deregister auto-scaling target on ${tableName} (${dimension}): ${err instanceof Error ? err.message : String(err)}. Run: aws application-autoscaling deregister-scalable-target --service-namespace dynamodb --resource-id ${resourceId} --scalable-dimension ${dimension}`);
21350
+ if (!isObjectNotFound(err)) warn(`Could not deregister auto-scaling target on ${tableName} (${dimension}): ${describeAwsFailure(err).detail}. Run: aws application-autoscaling deregister-scalable-target --service-namespace dynamodb --resource-id ${resourceId} --scalable-dimension ${dimension}`);
21349
21351
  }
21350
21352
  } finally {
21351
21353
  watch.dispose();
@@ -21426,7 +21428,7 @@ var DynamoDBGlobalTableProvider = class {
21426
21428
  policyToken = res.NextToken;
21427
21429
  } while (policyToken);
21428
21430
  } catch (err) {
21429
- this.logger.debug(`Could not probe existing auto-scaling targets on ${tableName} in ${region}: ${err instanceof Error ? err.message : String(err)} — re-asserting every target instead.`);
21431
+ this.logger.debug(`Could not probe existing auto-scaling targets on ${tableName} in ${region}: ${describeAwsFailure(err).detail} — re-asserting every target instead.`);
21430
21432
  return null;
21431
21433
  }
21432
21434
  }
@@ -21527,7 +21529,7 @@ var DynamoDBGlobalTableProvider = class {
21527
21529
  try {
21528
21530
  observedProtectionOn = (await this.dynamoDBClient.send(new DescribeTableCommand({ TableName: physicalId }))).Table?.DeletionProtectionEnabled === true;
21529
21531
  } catch (observeError) {
21530
- this.logger.debug(`Could not read DeletionProtectionEnabled on ${physicalId} before disabling it: ${observeError instanceof Error ? observeError.message : String(observeError)}`);
21532
+ this.logger.debug(`Could not read DeletionProtectionEnabled on ${physicalId} before disabling it: ${describeAwsFailure(observeError).detail}`);
21531
21533
  }
21532
21534
  await this.dynamoDBClient.send(new UpdateTableCommand({
21533
21535
  TableName: physicalId,
@@ -21538,10 +21540,10 @@ var DynamoDBGlobalTableProvider = class {
21538
21540
  try {
21539
21541
  await this.waitForTableActiveAfterUpdate(physicalId, logicalId, 600, budget);
21540
21542
  } catch (waitErr) {
21541
- this.logger.debug(`Could not wait for table ${physicalId} ACTIVE after protection flip: ${waitErr instanceof Error ? waitErr.message : String(waitErr)}`);
21543
+ this.logger.debug(`Could not wait for table ${physicalId} ACTIVE after protection flip: ${describeAwsFailure(waitErr).detail}`);
21542
21544
  }
21543
21545
  } catch (flipError) {
21544
- if (!(flipError instanceof ResourceNotFoundException$1)) this.logger.debug(`Could not disable DeletionProtectionEnabled on ${physicalId}: ${flipError instanceof Error ? flipError.message : String(flipError)}`);
21546
+ if (!(flipError instanceof ResourceNotFoundException$1)) this.logger.debug(`Could not disable DeletionProtectionEnabled on ${physicalId}: ${describeAwsFailure(flipError).detail}`);
21545
21547
  }
21546
21548
  let currentRegion;
21547
21549
  try {
@@ -21583,7 +21585,7 @@ var DynamoDBGlobalTableProvider = class {
21583
21585
  if (isInterruptedWaitError(describeErr)) throw describeErr;
21584
21586
  if (!(describeErr instanceof ResourceNotFoundException$1)) {
21585
21587
  const cause = describeErr instanceof Error ? describeErr : void 0;
21586
- throw new ProvisioningError(`Failed to describe DynamoDB GlobalTable ${logicalId} before delete: ${describeErr instanceof Error ? describeErr.message : String(describeErr)}`, resourceType, logicalId, physicalId, cause);
21588
+ throw new ProvisioningError(`Failed to describe DynamoDB GlobalTable ${logicalId} before delete: ${describeAwsFailure(describeErr).detail}`, resourceType, logicalId, physicalId, cause);
21587
21589
  }
21588
21590
  }
21589
21591
  try {
@@ -21742,7 +21744,7 @@ var DynamoDBGlobalTableProvider = class {
21742
21744
  this.logger.debug(`Cross-region replica ${regionLabel} returned RNF on ListTagsOfResource; omitting Tags`);
21743
21745
  entry["Tags"] = [];
21744
21746
  } else {
21745
- this.logger.warn(`Could not fetch tags for DynamoDB GlobalTable ${tableNameForSubs} in ${regionLabel}: ${tagErr instanceof Error ? tagErr.message : String(tagErr)}`);
21747
+ this.logger.warn(`Could not fetch tags for DynamoDB GlobalTable ${tableNameForSubs} in ${regionLabel}: ${describeAwsFailure(tagErr).detail}`);
21746
21748
  entry["Tags"] = [];
21747
21749
  }
21748
21750
  }
@@ -21809,7 +21811,7 @@ var DynamoDBGlobalTableProvider = class {
21809
21811
  };
21810
21812
  else if (ttlStatus === "DISABLED") {}
21811
21813
  } catch (ttlErr) {
21812
- this.logger.debug(`Could not read TimeToLive for ${tableNameForSubs}: ${ttlErr instanceof Error ? ttlErr.message : String(ttlErr)}`);
21814
+ this.logger.debug(`Could not read TimeToLive for ${tableNameForSubs}: ${describeAwsFailure(ttlErr).detail}`);
21813
21815
  }
21814
21816
  return result;
21815
21817
  } catch (err) {
@@ -21843,13 +21845,13 @@ var DynamoDBGlobalTableProvider = class {
21843
21845
  const ci = await client.send(new DescribeContributorInsightsCommand({ TableName: tableName }));
21844
21846
  if (ci.ContributorInsightsStatus) out["ContributorInsightsSpecification"] = { Enabled: ci.ContributorInsightsStatus === "ENABLED" };
21845
21847
  } catch (err) {
21846
- this.logger.debug(`Could not read ContributorInsights for ${tableName} in ${regionLabel}: ${err instanceof Error ? err.message : String(err)}`);
21848
+ this.logger.debug(`Could not read ContributorInsights for ${tableName} in ${regionLabel}: ${describeAwsFailure(err).detail}`);
21847
21849
  }
21848
21850
  try {
21849
21851
  const pitrStatus = (await client.send(new DescribeContinuousBackupsCommand({ TableName: tableName }))).ContinuousBackupsDescription?.PointInTimeRecoveryDescription?.PointInTimeRecoveryStatus;
21850
21852
  if (pitrStatus) out["PointInTimeRecoverySpecification"] = { PointInTimeRecoveryEnabled: pitrStatus === "ENABLED" };
21851
21853
  } catch (err) {
21852
- this.logger.debug(`Could not read PointInTimeRecovery for ${tableName} in ${regionLabel}: ${err instanceof Error ? err.message : String(err)}`);
21854
+ this.logger.debug(`Could not read PointInTimeRecovery for ${tableName} in ${regionLabel}: ${describeAwsFailure(err).detail}`);
21853
21855
  }
21854
21856
  try {
21855
21857
  const active = ((await client.send(new DescribeKinesisStreamingDestinationCommand({ TableName: tableName }))).KinesisDataStreamDestinations ?? []).find((d) => d.DestinationStatus === "ACTIVE" || d.DestinationStatus === "ENABLING");
@@ -21859,7 +21861,7 @@ var DynamoDBGlobalTableProvider = class {
21859
21861
  out["KinesisStreamSpecification"] = ksOut;
21860
21862
  }
21861
21863
  } catch (err) {
21862
- this.logger.debug(`Could not read KinesisStreamingDestination for ${tableName} in ${regionLabel}: ${err instanceof Error ? err.message : String(err)}`);
21864
+ this.logger.debug(`Could not read KinesisStreamingDestination for ${tableName} in ${regionLabel}: ${describeAwsFailure(err).detail}`);
21863
21865
  }
21864
21866
  return out;
21865
21867
  }
@@ -21955,7 +21957,7 @@ var DynamoDBGlobalTableProvider = class {
21955
21957
  TargetTrackingScalingPolicyConfiguration: tttConfig
21956
21958
  };
21957
21959
  } catch (err) {
21958
- this.logger.debug(`Could not read application-autoscaling settings for ${resourceId} (${scalableDimension}): ${err instanceof Error ? err.message : String(err)}`);
21960
+ this.logger.debug(`Could not read application-autoscaling settings for ${resourceId} (${scalableDimension}): ${describeAwsFailure(err).detail}`);
21959
21961
  return null;
21960
21962
  }
21961
21963
  }
@@ -23979,7 +23981,7 @@ var LogsLogGroupProvider = class {
23979
23981
  identifier: logGroupName
23980
23982
  });
23981
23983
  const manualStep = deleteCommand ? `Manual deletion may be required before the next deploy: ${deleteCommand}` : "Manual deletion may be required before the next deploy, via the console: the log group name cannot be reproduced safely on a command line.";
23982
- this.logger.warn(`Failed to clean up partially-created log group ${logicalId} (${logGroupName}): ${cleanupError instanceof Error ? cleanupError.message : String(cleanupError)}. ${manualStep}`);
23984
+ this.logger.warn(`Failed to clean up partially-created log group ${logicalId} (${logGroupName}): ${describeAwsFailure(cleanupError).detail}. ${manualStep}`);
23983
23985
  }
23984
23986
  throw innerError;
23985
23987
  }
@@ -24163,7 +24165,7 @@ var LogsLogGroupProvider = class {
24163
24165
  }));
24164
24166
  this.logger.debug(`Disabled DeletionProtectionEnabled on log group ${logicalId} before delete`);
24165
24167
  } catch (flipError) {
24166
- this.logger.debug(`Could not disable DeletionProtectionEnabled on ${physicalId}: ${flipError instanceof Error ? flipError.message : String(flipError)}`);
24168
+ this.logger.debug(`Could not disable DeletionProtectionEnabled on ${physicalId}: ${describeAwsFailure(flipError).detail}`);
24167
24169
  }
24168
24170
  try {
24169
24171
  await this.logsClient.send(new DeleteLogGroupCommand({ logGroupName: physicalId }));
@@ -24456,7 +24458,7 @@ var CloudWatchAlarmProvider = class {
24456
24458
  const compositeArn = response.CompositeAlarms?.[0]?.AlarmArn;
24457
24459
  if (compositeArn) return compositeArn;
24458
24460
  } catch (error) {
24459
- this.logger.debug(`Failed to describe alarm ${alarmName}, constructing ARN from config: ${error instanceof Error ? error.message : String(error)}`);
24461
+ this.logger.debug(`Failed to describe alarm ${alarmName}, constructing ARN from config: ${describeAwsFailure(error).detail}`);
24460
24462
  }
24461
24463
  try {
24462
24464
  const region = await this.cloudWatchClient.config.region() || process.env["AWS_REGION"] || "us-east-1";
@@ -24630,7 +24632,7 @@ var CloudWatchAlarmProvider = class {
24630
24632
  const tagsResp = await this.cloudWatchClient.send(new ListTagsForResourceCommand$4({ ResourceARN: alarm.AlarmArn }));
24631
24633
  result["Tags"] = normalizeAwsTagsToCfn(tagsResp.Tags);
24632
24634
  } catch (err) {
24633
- this.logger.debug(`CloudWatch ListTagsForResource(${alarm.AlarmArn}) failed: ${err instanceof Error ? err.message : String(err)}`);
24635
+ this.logger.debug(`CloudWatch ListTagsForResource(${alarm.AlarmArn}) failed: ${describeAwsFailure(err).detail}`);
24634
24636
  }
24635
24637
  return result;
24636
24638
  }
@@ -25662,7 +25664,7 @@ var SSMParameterProvider = class {
25662
25664
  try {
25663
25665
  return await this.buildParameterArnUnguarded(name, mask);
25664
25666
  } catch (error) {
25665
- this.logger.warn(mask(`Could not build the Arn attribute for SSM parameter ${name}: ${error instanceof Error ? error.message : String(error)}. The parameter itself is unaffected; the Arn is NOT recorded, so an Fn::GetAtt on it will fail until a later deploy records it.`));
25667
+ this.logger.warn(mask(`Could not build the Arn attribute for SSM parameter ${name}: ${describeAwsFailure(error).detail}. The parameter itself is unaffected; the Arn is NOT recorded, so an Fn::GetAtt on it will fail until a later deploy records it.`));
25666
25668
  return;
25667
25669
  }
25668
25670
  }
@@ -25739,7 +25741,7 @@ var SSMParameterProvider = class {
25739
25741
  maskSecrets: mask
25740
25742
  });
25741
25743
  const manualStep = deleteCommand ? `Manual deletion may be required before the next deploy: ${deleteCommand}` : "Manual deletion may be required before the next deploy, via the console: the parameter name cannot be reproduced safely on a command line, and a command naming the sanitized form would delete a DIFFERENT parameter.";
25742
- warn(`Failed to clean up partially-created SSM parameter ${logicalId} (${name}): ${cleanupError instanceof Error ? cleanupError.message : String(cleanupError)}. ${manualStep}`);
25744
+ warn(`Failed to clean up partially-created SSM parameter ${logicalId} (${name}): ${describeAwsFailure(cleanupError).detail}. ${manualStep}`);
25743
25745
  }
25744
25746
  throw innerError;
25745
25747
  }
@@ -26185,7 +26187,7 @@ var EventBridgeRuleProvider = class {
26185
26187
  }));
26186
26188
  this.logger.debug(`Cleaned up partially-created EventBridge rule ${logicalId} (${ruleName}) after wiring failure`);
26187
26189
  } catch (cleanupError) {
26188
- this.logger.warn(`Failed to clean up partially-created EventBridge rule ${logicalId} (${ruleName}): ${cleanupError instanceof Error ? cleanupError.message : String(cleanupError)}. Manual deletion may be required before the next deploy: aws events list-targets-by-rule --rule ${ruleName}${eventBusName ? ` --event-bus-name ${eventBusName}` : ""} | jq -r '.Targets[].Id' | xargs aws events remove-targets --rule ${ruleName}${eventBusName ? ` --event-bus-name ${eventBusName}` : ""} --ids; aws events delete-rule --name ${ruleName}${eventBusName ? ` --event-bus-name ${eventBusName}` : ""}`);
26190
+ this.logger.warn(`Failed to clean up partially-created EventBridge rule ${logicalId} (${ruleName}): ${describeAwsFailure(cleanupError).detail}. Manual deletion may be required before the next deploy: aws events list-targets-by-rule --rule ${ruleName}${eventBusName ? ` --event-bus-name ${eventBusName}` : ""} | jq -r '.Targets[].Id' | xargs aws events remove-targets --rule ${ruleName}${eventBusName ? ` --event-bus-name ${eventBusName}` : ""} --ids; aws events delete-rule --name ${ruleName}${eventBusName ? ` --event-bus-name ${eventBusName}` : ""}`);
26189
26191
  }
26190
26192
  throw innerError;
26191
26193
  }
@@ -26701,7 +26703,7 @@ var EventBridgeBusProvider = class {
26701
26703
  this.logger.debug(`EventBus ${physicalId} does not exist, skipping`);
26702
26704
  return;
26703
26705
  }
26704
- const msg = error instanceof Error ? error.message : String(error);
26706
+ const msg = describeAwsFailure(error).detail;
26705
26707
  if (msg.includes("does not exist")) {
26706
26708
  const clientRegion = await this.eventBridgeClient.config.region();
26707
26709
  assertRegionMatch(clientRegion, context?.expectedRegion, resourceType, logicalId, physicalId);
@@ -26747,7 +26749,7 @@ var EventBridgeBusProvider = class {
26747
26749
  }
26748
26750
  } catch (error) {
26749
26751
  if (error instanceof ResourceNotFoundException$2) return;
26750
- this.logger.debug(`Failed to list rules on bus ${busName}: ${error instanceof Error ? error.message : String(error)}`);
26752
+ this.logger.debug(`Failed to list rules on bus ${busName}: ${describeAwsFailure(error).detail}`);
26751
26753
  }
26752
26754
  }
26753
26755
  /**
@@ -27558,7 +27560,7 @@ var EC2Provider = class {
27558
27560
  await this.ec2Client.send(new DeleteVpcCommand({ VpcId: vpcId }));
27559
27561
  this.logger.debug(`Cleaned up partially-created VPC ${logicalId} (${vpcId}) after wiring failure`);
27560
27562
  } catch (cleanupError) {
27561
- this.logger.warn(`Failed to clean up partially-created VPC ${logicalId} (${vpcId}): ${cleanupError instanceof Error ? cleanupError.message : String(cleanupError)}. Manual deletion may be required before the next deploy: aws ec2 delete-vpc --vpc-id ${vpcId}`);
27563
+ this.logger.warn(`Failed to clean up partially-created VPC ${logicalId} (${vpcId}): ${describeAwsFailure(cleanupError).detail}. Manual deletion may be required before the next deploy: aws ec2 delete-vpc --vpc-id ${vpcId}`);
27562
27564
  }
27563
27565
  throw innerError;
27564
27566
  }
@@ -27624,7 +27626,7 @@ var EC2Provider = class {
27624
27626
  this.logger.debug(`VPC ${physicalId} does not exist, skipping deletion`);
27625
27627
  return;
27626
27628
  }
27627
- const msg = error instanceof Error ? error.message : String(error);
27629
+ const msg = describeAwsFailure(error).detail;
27628
27630
  if ((msg.includes("DependencyViolation") || msg.includes("has dependencies")) && attempt < maxAttempts) {
27629
27631
  this.logger.debug(`VPC ${physicalId} has dependencies (attempt ${attempt}/${maxAttempts}), retrying in ${attempt * 5}s...`);
27630
27632
  await new Promise((resolve) => setTimeout(resolve, attempt * 5e3));
@@ -27706,7 +27708,7 @@ var EC2Provider = class {
27706
27708
  await this.ec2Client.send(new DeleteSubnetCommand({ SubnetId: subnetId }));
27707
27709
  this.logger.debug(`Cleaned up partially-created Subnet ${logicalId} (${subnetId}) after wiring failure`);
27708
27710
  } catch (cleanupError) {
27709
- this.logger.warn(`Failed to clean up partially-created Subnet ${logicalId} (${subnetId}): ${cleanupError instanceof Error ? cleanupError.message : String(cleanupError)}. Manual deletion may be required before the next deploy: aws ec2 delete-subnet --subnet-id ${subnetId}`);
27711
+ this.logger.warn(`Failed to clean up partially-created Subnet ${logicalId} (${subnetId}): ${describeAwsFailure(cleanupError).detail}. Manual deletion may be required before the next deploy: aws ec2 delete-subnet --subnet-id ${subnetId}`);
27710
27712
  }
27711
27713
  throw innerError;
27712
27714
  }
@@ -27777,7 +27779,7 @@ var EC2Provider = class {
27777
27779
  try {
27778
27780
  if ((await this.ec2Client.send(new DescribeSubnetsCommand({ SubnetIds: [subnetId] }))).Subnets?.[0]?.MapPublicIpOnLaunch === expected) return;
27779
27781
  } catch (error) {
27780
- this.logger.debug(`MapPublicIpOnLaunch read-back for ${subnetId} failed (attempt ${attempt}/${maxAttempts}): ${error instanceof Error ? error.message : String(error)}`);
27782
+ this.logger.debug(`MapPublicIpOnLaunch read-back for ${subnetId} failed (attempt ${attempt}/${maxAttempts}): ${describeAwsFailure(error).detail}`);
27781
27783
  return;
27782
27784
  }
27783
27785
  if (attempt < maxAttempts) await this.sleep(100 * 2 ** (attempt - 1));
@@ -27798,7 +27800,7 @@ var EC2Provider = class {
27798
27800
  this.logger.debug(`Subnet ${physicalId} does not exist, skipping deletion`);
27799
27801
  return;
27800
27802
  }
27801
- const msg = error instanceof Error ? error.message : String(error);
27803
+ const msg = describeAwsFailure(error).detail;
27802
27804
  if ((msg.includes("has dependencies") || msg.includes("DependencyViolation")) && attempt < maxAttempts) {
27803
27805
  await this.cleanupSubnetLambdaEnis(physicalId);
27804
27806
  this.logger.debug(`Subnet ${physicalId} has dependencies (attempt ${attempt}/${maxAttempts}), retrying in ${attempt * 5}s...`);
@@ -27831,7 +27833,7 @@ var EC2Provider = class {
27831
27833
  status: ni.Status ?? "unknown"
27832
27834
  }));
27833
27835
  } catch (err) {
27834
- this.logger.debug(`cleanupSubnetLambdaEnis: DescribeNetworkInterfaces failed for ${subnetId}: ${err instanceof Error ? err.message : String(err)}`);
27836
+ this.logger.debug(`cleanupSubnetLambdaEnis: DescribeNetworkInterfaces failed for ${subnetId}: ${describeAwsFailure(err).detail}`);
27835
27837
  return;
27836
27838
  }
27837
27839
  if (enis.length === 0) return;
@@ -27840,7 +27842,7 @@ var EC2Provider = class {
27840
27842
  await this.ec2Client.send(new DeleteNetworkInterfaceCommand({ NetworkInterfaceId: eni.id }));
27841
27843
  this.logger.debug(`cleanupSubnetLambdaEnis: deleted Lambda ENI ${eni.id} in subnet ${subnetId}`);
27842
27844
  } catch (err) {
27843
- this.logger.debug(`cleanupSubnetLambdaEnis: ENI ${eni.id} (status=${eni.status}) not yet deletable: ${err instanceof Error ? err.message : String(err)}`);
27845
+ this.logger.debug(`cleanupSubnetLambdaEnis: ENI ${eni.id} (status=${eni.status}) not yet deletable: ${describeAwsFailure(err).detail}`);
27844
27846
  }
27845
27847
  }));
27846
27848
  }
@@ -28148,7 +28150,7 @@ var EC2Provider = class {
28148
28150
  maxDelay: 10
28149
28151
  }, { NatGatewayIds: [physicalId] });
28150
28152
  } catch (error) {
28151
- this.logger.warn(`Wait for NatGateway ${physicalId} deletion did not complete cleanly: ${error instanceof Error ? error.message : String(error)} — proceeding with downstream delete steps`);
28153
+ this.logger.warn(`Wait for NatGateway ${physicalId} deletion did not complete cleanly: ${describeAwsFailure(error).detail} — proceeding with downstream delete steps`);
28152
28154
  }
28153
28155
  this.logger.debug(`Successfully deleted NatGateway ${logicalId}`);
28154
28156
  }
@@ -28358,7 +28360,7 @@ var EC2Provider = class {
28358
28360
  await this.ec2Client.send(new DeleteSecurityGroupCommand({ GroupId: groupId }));
28359
28361
  this.logger.debug(`Cleaned up partially-created SecurityGroup ${logicalId} (${groupId}) after wiring failure`);
28360
28362
  } catch (cleanupError) {
28361
- this.logger.warn(`Failed to clean up partially-created SecurityGroup ${logicalId} (${groupId}): ${cleanupError instanceof Error ? cleanupError.message : String(cleanupError)}. Manual deletion may be required before the next deploy: aws ec2 delete-security-group --group-id ${groupId}`);
28363
+ this.logger.warn(`Failed to clean up partially-created SecurityGroup ${logicalId} (${groupId}): ${describeAwsFailure(cleanupError).detail}. Manual deletion may be required before the next deploy: aws ec2 delete-security-group --group-id ${groupId}`);
28362
28364
  }
28363
28365
  throw innerError;
28364
28366
  }
@@ -28482,7 +28484,7 @@ var EC2Provider = class {
28482
28484
  this.logger.debug(`SecurityGroup ${physicalId} does not exist, skipping deletion`);
28483
28485
  return;
28484
28486
  }
28485
- const msg = error instanceof Error ? error.message : String(error);
28487
+ const msg = describeAwsFailure(error).detail;
28486
28488
  if (msg.includes("dependent object") && attempt < maxAttempts) {
28487
28489
  await this.cleanupSecurityGroupLambdaEnis(physicalId);
28488
28490
  this.logger.debug(`SecurityGroup ${physicalId} has dependent objects (attempt ${attempt}/${maxAttempts}), retrying in ${attempt * 5}s...`);
@@ -28512,7 +28514,7 @@ var EC2Provider = class {
28512
28514
  status: ni.Status ?? "unknown"
28513
28515
  }));
28514
28516
  } catch (err) {
28515
- this.logger.debug(`cleanupSecurityGroupLambdaEnis: DescribeNetworkInterfaces failed for ${groupId}: ${err instanceof Error ? err.message : String(err)}`);
28517
+ this.logger.debug(`cleanupSecurityGroupLambdaEnis: DescribeNetworkInterfaces failed for ${groupId}: ${describeAwsFailure(err).detail}`);
28516
28518
  return;
28517
28519
  }
28518
28520
  if (enis.length === 0) return;
@@ -28521,7 +28523,7 @@ var EC2Provider = class {
28521
28523
  await this.ec2Client.send(new DeleteNetworkInterfaceCommand({ NetworkInterfaceId: eni.id }));
28522
28524
  this.logger.debug(`cleanupSecurityGroupLambdaEnis: deleted Lambda ENI ${eni.id} for SG ${groupId}`);
28523
28525
  } catch (err) {
28524
- this.logger.debug(`cleanupSecurityGroupLambdaEnis: ENI ${eni.id} (status=${eni.status}) not yet deletable: ${err instanceof Error ? err.message : String(err)}`);
28526
+ this.logger.debug(`cleanupSecurityGroupLambdaEnis: ENI ${eni.id} (status=${eni.status}) not yet deletable: ${describeAwsFailure(err).detail}`);
28525
28527
  }
28526
28528
  }));
28527
28529
  }
@@ -28583,7 +28585,7 @@ var EC2Provider = class {
28583
28585
  }
28584
28586
  continue;
28585
28587
  }
28586
- this.logger.debug(`DescribeSecurityGroups for SecurityGroup ${groupId} failed (${errorClass}); omitting the VpcId attribute: ${error instanceof Error ? error.message : String(error)}`);
28588
+ this.logger.debug(`DescribeSecurityGroups for SecurityGroup ${groupId} failed (${errorClass}); omitting the VpcId attribute: ${describeAwsFailure(error).detail}`);
28587
28589
  return;
28588
28590
  }
28589
28591
  }
@@ -28720,7 +28722,7 @@ var EC2Provider = class {
28720
28722
  }
28721
28723
  return ids[0];
28722
28724
  } catch (error) {
28723
- this.logger.debug(`SecurityGroupIngress ${logicalId}: could not look up the existing rule id on ${groupId} (${error instanceof Error ? error.message : String(error)}) — not recording an Id attribute`);
28725
+ this.logger.debug(`SecurityGroupIngress ${logicalId}: could not look up the existing rule id on ${groupId} (${describeAwsFailure(error).detail}) — not recording an Id attribute`);
28724
28726
  return;
28725
28727
  }
28726
28728
  }
@@ -28843,7 +28845,7 @@ var EC2Provider = class {
28843
28845
  runInstancesToken.release();
28844
28846
  this.logger.debug(`Terminate requested for partially-created EC2 Instance ${logicalId} (${instanceId}) after wiring failure (not waiting for terminated state)`);
28845
28847
  } catch (cleanupError) {
28846
- this.logger.warn(`Failed to terminate partially-created EC2 Instance ${logicalId} (${instanceId}): ${cleanupError instanceof Error ? cleanupError.message : String(cleanupError)}. THE INSTANCE IS STILL RUNNING AND BILLING. Manual termination required: aws ec2 terminate-instances --instance-ids ${instanceId}`);
28848
+ this.logger.warn(`Failed to terminate partially-created EC2 Instance ${logicalId} (${instanceId}): ${describeAwsFailure(cleanupError).detail}. THE INSTANCE IS STILL RUNNING AND BILLING. Manual termination required: aws ec2 terminate-instances --instance-ids ${instanceId}`);
28847
28849
  }
28848
28850
  throw innerError;
28849
28851
  }
@@ -28934,7 +28936,7 @@ var EC2Provider = class {
28934
28936
  associated = true;
28935
28937
  break;
28936
28938
  } catch (error) {
28937
- const msg = error instanceof Error ? error.message : String(error);
28939
+ const msg = describeAwsFailure(error).detail;
28938
28940
  if (msg.includes("IncorrectState") || msg.includes("already associated")) {
28939
28941
  this.logger.debug(`IAM instance profile already associated with instance ${instanceId} (${logicalId})`);
28940
28942
  associated = true;
@@ -28975,7 +28977,7 @@ var EC2Provider = class {
28975
28977
  Values: [instanceId]
28976
28978
  }] }))).IamInstanceProfileAssociations?.some((a) => a.State === "associated") ?? false;
28977
28979
  } catch (err) {
28978
- this.logger.debug(`DescribeIamInstanceProfileAssociations failed for ${instanceId}: ${err instanceof Error ? err.message : String(err)}`);
28980
+ this.logger.debug(`DescribeIamInstanceProfileAssociations failed for ${instanceId}: ${describeAwsFailure(err).detail}`);
28979
28981
  return false;
28980
28982
  }
28981
28983
  }
@@ -29078,7 +29080,7 @@ var EC2Provider = class {
29078
29080
  this.logger.debug(`EC2 Instance ${physicalId} already terminated (not found), treating as success`);
29079
29081
  return;
29080
29082
  }
29081
- const msg = error instanceof Error ? error.message : String(error);
29083
+ const msg = describeAwsFailure(error).detail;
29082
29084
  if (removeProtection && isTerminationProtectionPropagationError(msg) && attempt < maxTerminateAttempts) {
29083
29085
  this.logger.debug(`Terminate of EC2 Instance ${logicalId} raced the DisableApiTermination flip-off (attempt ${attempt}/${maxTerminateAttempts}); re-flipping and retrying`);
29084
29086
  await disableInstanceApiTermination(this.ec2Client, physicalId, this.logger);
@@ -29525,7 +29527,7 @@ var EC2Provider = class {
29525
29527
  }));
29526
29528
  this.logger.debug(`Applied ${tags.length} tag(s) to ${logicalId}`);
29527
29529
  } catch (error) {
29528
- this.logger.warn(`Failed to apply tags to ${logicalId}: ${error instanceof Error ? error.message : String(error)}`);
29530
+ this.logger.warn(`Failed to apply tags to ${logicalId}: ${describeAwsFailure(error).detail}`);
29529
29531
  }
29530
29532
  }
29531
29533
  /**
@@ -29556,7 +29558,7 @@ var EC2Provider = class {
29556
29558
  }));
29557
29559
  this.logger.debug(`Removed ${tagsToRemove.length} tag(s) from ${resourceId}`);
29558
29560
  } catch (error) {
29559
- this.logger.warn(`Failed to remove tags from ${resourceId}: ${error instanceof Error ? error.message : String(error)}`);
29561
+ this.logger.warn(`Failed to remove tags from ${resourceId}: ${describeAwsFailure(error).detail}`);
29560
29562
  }
29561
29563
  if (tagsToAdd.length > 0) try {
29562
29564
  await this.ec2Client.send(new CreateTagsCommand({
@@ -29565,7 +29567,7 @@ var EC2Provider = class {
29565
29567
  }));
29566
29568
  this.logger.debug(`Added/updated ${tagsToAdd.length} tag(s) on ${resourceId}`);
29567
29569
  } catch (error) {
29568
- this.logger.warn(`Failed to add tags on ${resourceId}: ${error instanceof Error ? error.message : String(error)}`);
29570
+ this.logger.warn(`Failed to add tags on ${resourceId}: ${describeAwsFailure(error).detail}`);
29569
29571
  }
29570
29572
  }
29571
29573
  /**
@@ -29622,7 +29624,7 @@ var EC2Provider = class {
29622
29624
  if (elapsed >= totalBudgetMs) throw error;
29623
29625
  attempt += 1;
29624
29626
  const sleepMs = Math.min(delay, totalBudgetMs - elapsed);
29625
- const message = error instanceof Error ? error.message : String(error);
29627
+ const message = describeAwsFailure(error).detail;
29626
29628
  this.logger.debug(`${opts.description}: dependency still mapped (attempt ${attempt}, retrying in ${sleepMs}ms): ${message}`);
29627
29629
  await this.sleep(sleepMs);
29628
29630
  delay = Math.min(delay * 2, maxDelayMs);
@@ -30003,7 +30005,7 @@ var EC2Provider = class {
30003
30005
  }] }))).IamInstanceProfileAssociations?.find((a) => a.State === "associated" || a.State === "associating");
30004
30006
  if (live?.IamInstanceProfile?.Arn !== void 0) result["IamInstanceProfile"] = live.IamInstanceProfile.Arn;
30005
30007
  } catch (error) {
30006
- this.logger.warn(`Could not backfill IamInstanceProfile for ${physicalId} during the --no-wait capture (${error instanceof Error ? error.message : String(error)}); the field is omitted from the observed snapshot`);
30008
+ this.logger.warn(`Could not backfill IamInstanceProfile for ${physicalId} during the --no-wait capture (${describeAwsFailure(error).detail}); the field is omitted from the observed snapshot`);
30007
30009
  }
30008
30010
  const volumeIds = (instance.BlockDeviceMappings ?? []).filter((m) => m.Ebs?.VolumeId !== void 0).map((m) => m.Ebs.VolumeId);
30009
30011
  let volumesById = /* @__PURE__ */ new Map();
@@ -30011,7 +30013,7 @@ var EC2Provider = class {
30011
30013
  const volResp = await this.ec2Client.send(new DescribeVolumesCommand({ VolumeIds: volumeIds }));
30012
30014
  for (const v of volResp.Volumes ?? []) if (v.VolumeId !== void 0) volumesById.set(v.VolumeId, v);
30013
30015
  } catch (err) {
30014
- this.logger.debug(`DescribeVolumes(${volumeIds.join(",")}) failed: ${err instanceof Error ? err.message : String(err)}`);
30016
+ this.logger.debug(`DescribeVolumes(${volumeIds.join(",")}) failed: ${describeAwsFailure(err).detail}`);
30015
30017
  volumesById = /* @__PURE__ */ new Map();
30016
30018
  }
30017
30019
  const blockMappings = [];
@@ -30044,13 +30046,13 @@ var EC2Provider = class {
30044
30046
  }));
30045
30047
  if (attrResp.DisableApiTermination?.Value !== void 0) result["DisableApiTermination"] = attrResp.DisableApiTermination.Value;
30046
30048
  } catch (err) {
30047
- this.logger.debug(`DescribeInstanceAttribute(disableApiTermination, ${physicalId}) failed: ${err instanceof Error ? err.message : String(err)}`);
30049
+ this.logger.debug(`DescribeInstanceAttribute(disableApiTermination, ${physicalId}) failed: ${describeAwsFailure(err).detail}`);
30048
30050
  }
30049
30051
  try {
30050
30052
  const cpuCredits = (await this.ec2Client.send(new DescribeInstanceCreditSpecificationsCommand({ InstanceIds: [physicalId] }))).InstanceCreditSpecifications?.[0]?.CpuCredits;
30051
30053
  if (cpuCredits !== void 0) result["CreditSpecification"] = { CPUCredits: cpuCredits };
30052
30054
  } catch (err) {
30053
- this.logger.debug(`DescribeInstanceCreditSpecifications(${physicalId}) failed: ${err instanceof Error ? err.message : String(err)}`);
30055
+ this.logger.debug(`DescribeInstanceCreditSpecifications(${physicalId}) failed: ${describeAwsFailure(err).detail}`);
30054
30056
  }
30055
30057
  return result;
30056
30058
  }
@@ -30818,7 +30820,7 @@ var ApiGatewayProvider = class ApiGatewayProvider {
30818
30820
  await this.apiGatewayClient.send(new UpdateAccountCommand({ patchOperations }));
30819
30821
  return;
30820
30822
  } catch (error) {
30821
- const message = error instanceof Error ? error.message : String(error);
30823
+ const message = describeAwsFailure(error).detail;
30822
30824
  if ((message.toLowerCase().includes("not authorized") || message.toLowerCase().includes("does not have required permissions") || message.toLowerCase().includes("the role arn does not have required trust") || message.toLowerCase().includes("too many requests")) && attempt < ApiGatewayProvider.MAX_IAM_RETRIES) {
30823
30825
  this.logger.warn(`IAM propagation delay for ${logicalId} (attempt ${attempt}/${ApiGatewayProvider.MAX_IAM_RETRIES}), retrying in ${ApiGatewayProvider.IAM_RETRY_DELAY_MS / 1e3}s...`);
30824
30826
  await this.sleep(ApiGatewayProvider.IAM_RETRY_DELAY_MS);
@@ -31029,8 +31031,8 @@ var ApiGatewayProvider = class ApiGatewayProvider {
31029
31031
  try {
31030
31032
  await this.deleteResource(logicalId, physicalId, resourceType, previousProperties);
31031
31033
  } catch (error) {
31032
- orphanReason = `old API Gateway Resource ${physicalId} could not be deleted: ${String(error)}`;
31033
- this.logger.warn(`Failed to delete old API Gateway Resource ${physicalId} during replacement: ${String(error)}. The old resource may be orphaned and require manual cleanup.`);
31034
+ orphanReason = `old API Gateway Resource ${physicalId} could not be deleted: ${safeStringify(error)}`;
31035
+ this.logger.warn(`Failed to delete old API Gateway Resource ${physicalId} during replacement: ${safeStringify(error)}. The old resource may be orphaned and require manual cleanup.`);
31034
31036
  }
31035
31037
  const base = {
31036
31038
  physicalId: createResult.physicalId,
@@ -31205,7 +31207,7 @@ var ApiGatewayProvider = class ApiGatewayProvider {
31205
31207
  stageName
31206
31208
  }));
31207
31209
  } catch (cleanupError) {
31208
- this.logger.warn(`Failed to clean up stage ${stageName} after a post-create patch failure: ${cleanupError instanceof Error ? cleanupError.message : String(cleanupError)}`);
31210
+ this.logger.warn(`Failed to clean up stage ${stageName} after a post-create patch failure: ${describeAwsFailure(cleanupError).detail}`);
31209
31211
  }
31210
31212
  throw patchError;
31211
31213
  }
@@ -31552,7 +31554,7 @@ var ApiGatewayProvider = class ApiGatewayProvider {
31552
31554
  }));
31553
31555
  this.logger.debug(`Cleaned up partially-created API Gateway Method ${logicalId} (${restApiId}/${resourceId}/${httpMethod}) after wiring failure`);
31554
31556
  } catch (cleanupError) {
31555
- this.logger.warn(`Failed to clean up partially-created API Gateway Method ${logicalId} (${restApiId}/${resourceId}/${httpMethod}): ${cleanupError instanceof Error ? cleanupError.message : String(cleanupError)}. Manual deletion may be required before the next deploy: aws apigateway delete-method --rest-api-id ${restApiId} --resource-id ${resourceId} --http-method ${httpMethod}`);
31557
+ this.logger.warn(`Failed to clean up partially-created API Gateway Method ${logicalId} (${restApiId}/${resourceId}/${httpMethod}): ${describeAwsFailure(cleanupError).detail}. Manual deletion may be required before the next deploy: aws apigateway delete-method --rest-api-id ${restApiId} --resource-id ${resourceId} --http-method ${httpMethod}`);
31556
31558
  }
31557
31559
  throw innerError;
31558
31560
  }
@@ -34564,7 +34566,7 @@ var CloudFrontDistributionProvider = class {
34564
34566
  if (cfnTags.length > 0) result["Tags"] = cfnTags;
34565
34567
  }
34566
34568
  } catch (error) {
34567
- this.logger.debug(`Tag read for CloudFront Distribution ${physicalId} failed during drift read: ${error instanceof Error ? error.message : String(error)}`);
34569
+ this.logger.debug(`Tag read for CloudFront Distribution ${physicalId} failed during drift read: ${describeAwsFailure(error).detail}`);
34568
34570
  }
34569
34571
  return result;
34570
34572
  }
@@ -34674,7 +34676,7 @@ var CloudFrontDistributionProvider = class {
34674
34676
  response = await this.cloudFrontClient.send(new GetDistributionCommand({ Id: distributionId }));
34675
34677
  } catch (error) {
34676
34678
  if (error instanceof NoSuchDistribution) throw error;
34677
- this.logger.debug(`Distribution ${distributionId} status read failed (${error instanceof Error ? error.message : String(error)}); retrying`);
34679
+ this.logger.debug(`Distribution ${distributionId} status read failed (${describeAwsFailure(error).detail}); retrying`);
34678
34680
  }
34679
34681
  if (response) {
34680
34682
  const status = response.Distribution?.Status;
@@ -35567,7 +35569,7 @@ var AgentCoreRuntimeProvider = class {
35567
35569
  attributes: this.buildAttributes(resp, resp.agentRuntimeName)
35568
35570
  };
35569
35571
  } catch (err) {
35570
- this.logger.debug(`Could not enrich imported BedrockAgentCore Runtime ${physicalId} attributes (${err instanceof Error ? err.message : String(err)}); recording AgentRuntimeId only (Fn::GetAtt resolves live via getAttribute)`);
35572
+ this.logger.debug(`Could not enrich imported BedrockAgentCore Runtime ${physicalId} attributes (${describeAwsFailure(err).detail}); recording AgentRuntimeId only (Fn::GetAtt resolves live via getAttribute)`);
35571
35573
  return {
35572
35574
  physicalId,
35573
35575
  attributes: { AgentRuntimeId: physicalId }
@@ -36041,7 +36043,7 @@ var AgentCoreEvaluatorProvider = class {
36041
36043
  try {
36042
36044
  result["Tags"] = tagMapToCfnList((await this.client.send(new ListTagsForResourceCommand$6({ resourceArn: physicalId }))).tags ?? {});
36043
36045
  } catch (err) {
36044
- this.logger.debug(`Failed to read tags for evaluator ${physicalId}: ${err instanceof Error ? err.message : String(err)}`);
36046
+ this.logger.debug(`Failed to read tags for evaluator ${physicalId}: ${describeAwsFailure(err).detail}`);
36045
36047
  }
36046
36048
  return result;
36047
36049
  }
@@ -36983,7 +36985,7 @@ var ECSProvider = class {
36983
36985
  }));
36984
36986
  this.logger.warn(`Deleted partially-created ECS service ${logicalId} (${service.serviceArn}) after the steady-state wait failed, so the next deploy's CreateService does not collide on the name. Its stopped tasks remain inspectable for about an hour: aws ecs list-tasks${clusterArg} --desired-status STOPPED`);
36985
36987
  } catch (cleanupError) {
36986
- this.logger.warn(`Failed to clean up partially-created ECS service ${logicalId} (${service.serviceArn}): ${cleanupError instanceof Error ? cleanupError.message : String(cleanupError)}. Manual deletion may be required before the next deploy: aws ecs delete-service${clusterArg} --service ${service.serviceArn} --force`);
36988
+ this.logger.warn(`Failed to clean up partially-created ECS service ${logicalId} (${service.serviceArn}): ${describeAwsFailure(cleanupError).detail}. Manual deletion may be required before the next deploy: aws ecs delete-service${clusterArg} --service ${service.serviceArn} --force`);
36987
36989
  }
36988
36990
  throw new Error(`ECS service ${logicalId} did not reach steady state under --full-wait: ${waitError instanceof Error ? waitError.message : String(waitError)}. Inspect why its tasks stopped (stopped tasks stay visible for about an hour): aws ecs list-tasks${clusterArg} --desired-status STOPPED, then aws ecs describe-tasks${clusterArg} --tasks <task-arn> --query 'tasks[].[stoppedReason,containers[].reason]'`, { cause: waitError });
36989
36991
  }
@@ -38863,7 +38865,7 @@ var ELBv2Provider = class {
38863
38865
  try {
38864
38866
  zones = (await this.getClient().send(new DescribeCapacityReservationCommand({ LoadBalancerArn: lbArn }))).CapacityReservationState ?? [];
38865
38867
  } catch (probeError) {
38866
- this.logger.debug(`DescribeCapacityReservation for ${logicalId} failed transiently (attempt ${attempt + 1}/${maxAttempts}): ${probeError instanceof Error ? probeError.message : String(probeError)}`);
38868
+ this.logger.debug(`DescribeCapacityReservation for ${logicalId} failed transiently (attempt ${attempt + 1}/${maxAttempts}): ${describeAwsFailure(probeError).detail}`);
38867
38869
  await capacityReservationDelays.sleep(intervalMs);
38868
38870
  continue;
38869
38871
  }
@@ -38889,7 +38891,7 @@ var ELBv2Provider = class {
38889
38891
  }));
38890
38892
  this.logger.debug(`Disabled deletion_protection.enabled on LoadBalancer ${logicalId} before delete`);
38891
38893
  } catch (flipError) {
38892
- if (!this.isNotFoundError(flipError)) this.logger.debug(`Could not disable deletion_protection.enabled on ${physicalId}: ${flipError instanceof Error ? flipError.message : String(flipError)}`);
38894
+ if (!this.isNotFoundError(flipError)) this.logger.debug(`Could not disable deletion_protection.enabled on ${physicalId}: ${describeAwsFailure(flipError).detail}`);
38893
38895
  }
38894
38896
  try {
38895
38897
  await this.getClient().send(new DeleteLoadBalancerCommand({ LoadBalancerArn: physicalId }));
@@ -39593,7 +39595,7 @@ var ELBv2Provider = class {
39593
39595
  }
39594
39596
  result["Targets"] = targets;
39595
39597
  } catch (err) {
39596
- this.logger.debug(`ELBv2 DescribeTargetHealth(${targetGroupArn}) failed: ${err instanceof Error ? err.message : String(err)}`);
39598
+ this.logger.debug(`ELBv2 DescribeTargetHealth(${targetGroupArn}) failed: ${describeAwsFailure(err).detail}`);
39597
39599
  }
39598
39600
  }
39599
39601
  /**
@@ -39681,7 +39683,7 @@ var ELBv2Provider = class {
39681
39683
  const tagDesc = (await this.getClient().send(new DescribeTagsCommand({ ResourceArns: [arn] }))).TagDescriptions?.[0];
39682
39684
  result["Tags"] = normalizeAwsTagsToCfn(tagDesc?.Tags);
39683
39685
  } catch (err) {
39684
- this.logger.debug(`ELBv2 DescribeTags(${arn}) failed: ${err instanceof Error ? err.message : String(err)}`);
39686
+ this.logger.debug(`ELBv2 DescribeTags(${arn}) failed: ${describeAwsFailure(err).detail}`);
39685
39687
  }
39686
39688
  }
39687
39689
  /**
@@ -39983,7 +39985,7 @@ var RDSProvider = class {
39983
39985
  ApplyImmediately: true
39984
39986
  }));
39985
39987
  } catch (disableError) {
39986
- this.logger.debug(`Could not disable DeletionProtection on partially-created DBCluster ${dbClusterIdentifier}: ${disableError instanceof Error ? disableError.message : String(disableError)} (proceeding with DeleteDBCluster anyway)`);
39988
+ this.logger.debug(`Could not disable DeletionProtection on partially-created DBCluster ${dbClusterIdentifier}: ${describeAwsFailure(disableError).detail} (proceeding with DeleteDBCluster anyway)`);
39987
39989
  }
39988
39990
  await this.getClient().send(new DeleteDBClusterCommand({
39989
39991
  DBClusterIdentifier: dbClusterIdentifier,
@@ -39991,7 +39993,7 @@ var RDSProvider = class {
39991
39993
  }));
39992
39994
  this.logger.debug(`Delete requested for partially-created DBCluster ${logicalId} (${dbClusterIdentifier}) after wiring failure (not waiting for deleted state)`);
39993
39995
  } catch (cleanupError) {
39994
- this.logger.warn(`Failed to delete partially-created DBCluster ${logicalId} (${dbClusterIdentifier}): ${cleanupError instanceof Error ? cleanupError.message : String(cleanupError)}. THE CLUSTER IS STILL RUNNING AND BILLING. Manual cleanup required: ${wantsDeletionProtection ? `aws rds modify-db-cluster --db-cluster-identifier ${dbClusterIdentifier} --no-deletion-protection --apply-immediately; ` : ""}aws rds delete-db-cluster --db-cluster-identifier ${dbClusterIdentifier} --skip-final-snapshot`);
39996
+ this.logger.warn(`Failed to delete partially-created DBCluster ${logicalId} (${dbClusterIdentifier}): ${describeAwsFailure(cleanupError).detail}. THE CLUSTER IS STILL RUNNING AND BILLING. Manual cleanup required: ${wantsDeletionProtection ? `aws rds modify-db-cluster --db-cluster-identifier ${dbClusterIdentifier} --no-deletion-protection --apply-immediately; ` : ""}aws rds delete-db-cluster --db-cluster-identifier ${dbClusterIdentifier} --skip-final-snapshot`);
39995
39997
  }
39996
39998
  throw innerError;
39997
39999
  }
@@ -40058,7 +40060,7 @@ var RDSProvider = class {
40058
40060
  }));
40059
40061
  this.logger.debug(`Disabled DeletionProtection on DBCluster ${logicalId} before delete`);
40060
40062
  } catch (disableError) {
40061
- if (!this.isNotFoundError(disableError, "DBClusterNotFoundFault")) this.logger.debug(`Could not disable deletion protection for ${physicalId}: ${disableError instanceof Error ? disableError.message : String(disableError)}`);
40063
+ if (!this.isNotFoundError(disableError, "DBClusterNotFoundFault")) this.logger.debug(`Could not disable deletion protection for ${physicalId}: ${describeAwsFailure(disableError).detail}`);
40062
40064
  }
40063
40065
  const finalSnapshotId = context?.finalSnapshotIdentifier;
40064
40066
  await this.getClient().send(new DeleteDBClusterCommand({
@@ -40186,7 +40188,7 @@ var RDSProvider = class {
40186
40188
  }));
40187
40189
  this.logger.debug(`Disabled DeletionProtection on DBInstance ${logicalId} before delete`);
40188
40190
  } catch (disableError) {
40189
- if (!this.isNotFoundError(disableError, "DBInstanceNotFoundFault")) this.logger.debug(`Could not disable deletion protection for ${physicalId}: ${disableError instanceof Error ? disableError.message : String(disableError)}`);
40191
+ if (!this.isNotFoundError(disableError, "DBInstanceNotFoundFault")) this.logger.debug(`Could not disable deletion protection for ${physicalId}: ${describeAwsFailure(disableError).detail}`);
40190
40192
  }
40191
40193
  const finalSnapshotId = properties?.["DBClusterIdentifier"] === void 0 ? context?.finalSnapshotIdentifier : void 0;
40192
40194
  await this.getClient().send(new DeleteDBInstanceCommand({
@@ -40476,7 +40478,7 @@ var RDSProvider = class {
40476
40478
  const tagsResp = await this.getClient().send(new ListTagsForResourceCommand$10({ ResourceName: arn }));
40477
40479
  result["Tags"] = normalizeAwsTagsToCfn(tagsResp.TagList);
40478
40480
  } catch (err) {
40479
- this.logger.debug(`RDS ListTagsForResource(${arn}) failed: ${err instanceof Error ? err.message : String(err)}`);
40481
+ this.logger.debug(`RDS ListTagsForResource(${arn}) failed: ${describeAwsFailure(err).detail}`);
40480
40482
  }
40481
40483
  }
40482
40484
  async importDBInstance(input) {
@@ -40776,7 +40778,7 @@ var RDSDBProxyProvider = class {
40776
40778
  const tagResp = await client.send(new ListTagsForResourceCommand$10({ ResourceName: p.DBProxyArn }));
40777
40779
  result["Tags"] = normalizeAwsTagsToCfn(tagResp.TagList ?? []);
40778
40780
  } catch (error) {
40779
- this.logger.debug(`ListTagsForResource failed for ${physicalId}: ${error instanceof Error ? error.message : String(error)}`);
40781
+ this.logger.debug(`ListTagsForResource failed for ${physicalId}: ${describeAwsFailure(error).detail}`);
40780
40782
  result["Tags"] = [];
40781
40783
  }
40782
40784
  else result["Tags"] = [];
@@ -40793,7 +40795,7 @@ var RDSDBProxyProvider = class {
40793
40795
  arn = (await client.send(new DescribeDBProxiesCommand({ DBProxyName: physicalId }))).DBProxies?.[0]?.DBProxyArn;
40794
40796
  if (arn) this.attributeCache.set(arnCacheKey, arn);
40795
40797
  } catch (error) {
40796
- this.logger.debug(`Skipping tag diff for ${physicalId} (no ARN): ${error instanceof Error ? error.message : String(error)}`);
40798
+ this.logger.debug(`Skipping tag diff for ${physicalId} (no ARN): ${describeAwsFailure(error).detail}`);
40797
40799
  return;
40798
40800
  }
40799
40801
  if (!arn) return;
@@ -41087,7 +41089,7 @@ var RDSDBProxyEndpointProvider = class {
41087
41089
  const tagResp = await client.send(new ListTagsForResourceCommand$10({ ResourceName: e.DBProxyEndpointArn }));
41088
41090
  result["Tags"] = normalizeAwsTagsToCfn(tagResp.TagList ?? []);
41089
41091
  } catch (error) {
41090
- this.logger.debug(`ListTagsForResource failed for ${physicalId}: ${error instanceof Error ? error.message : String(error)}`);
41092
+ this.logger.debug(`ListTagsForResource failed for ${physicalId}: ${describeAwsFailure(error).detail}`);
41091
41093
  result["Tags"] = [];
41092
41094
  }
41093
41095
  else result["Tags"] = [];
@@ -41104,7 +41106,7 @@ var RDSDBProxyEndpointProvider = class {
41104
41106
  arn = (await client.send(new DescribeDBProxyEndpointsCommand({ DBProxyEndpointName: physicalId }))).DBProxyEndpoints?.[0]?.DBProxyEndpointArn;
41105
41107
  if (arn) this.attributeCache.set(arnCacheKey, arn);
41106
41108
  } catch (error) {
41107
- this.logger.debug(`Skipping tag diff for ${physicalId} (no ARN): ${error instanceof Error ? error.message : String(error)}`);
41109
+ this.logger.debug(`Skipping tag diff for ${physicalId} (no ARN): ${describeAwsFailure(error).detail}`);
41108
41110
  return;
41109
41111
  }
41110
41112
  if (!arn) return;
@@ -41730,7 +41732,7 @@ var DocDBProvider = class {
41730
41732
  }));
41731
41733
  this.logger.debug(`Disabled DeletionProtection on DocDB DBCluster ${logicalId} before delete`);
41732
41734
  } catch (disableError) {
41733
- if (!this.isNotFoundError(disableError, "DBClusterNotFoundFault")) this.logger.debug(`Could not disable deletion protection for ${physicalId}: ${disableError instanceof Error ? disableError.message : String(disableError)}`);
41735
+ if (!this.isNotFoundError(disableError, "DBClusterNotFoundFault")) this.logger.debug(`Could not disable deletion protection for ${physicalId}: ${describeAwsFailure(disableError).detail}`);
41734
41736
  }
41735
41737
  const finalSnapshotId = context?.finalSnapshotIdentifier;
41736
41738
  await this.getClient().send(new DeleteDBClusterCommand$1({
@@ -42069,7 +42071,7 @@ var DocDBProvider = class {
42069
42071
  const tagsResp = await this.getClient().send(new ListTagsForResourceCommand$12({ ResourceName: arn }));
42070
42072
  result["Tags"] = normalizeAwsTagsToCfn(tagsResp.TagList);
42071
42073
  } catch (err) {
42072
- this.logger.debug(`DocDB ListTagsForResource(${arn}) failed: ${err instanceof Error ? err.message : String(err)}`);
42074
+ this.logger.debug(`DocDB ListTagsForResource(${arn}) failed: ${describeAwsFailure(err).detail}`);
42073
42075
  }
42074
42076
  }
42075
42077
  async importDBInstance(input) {
@@ -42367,7 +42369,7 @@ var NeptuneProvider = class {
42367
42369
  }));
42368
42370
  this.logger.debug(`Disabled DeletionProtection on Neptune DBCluster ${logicalId} before delete`);
42369
42371
  } catch (disableError) {
42370
- if (!this.isNotFoundError(disableError, "DBClusterNotFoundFault")) this.logger.debug(`Could not disable deletion protection for ${physicalId}: ${disableError instanceof Error ? disableError.message : String(disableError)}`);
42372
+ if (!this.isNotFoundError(disableError, "DBClusterNotFoundFault")) this.logger.debug(`Could not disable deletion protection for ${physicalId}: ${describeAwsFailure(disableError).detail}`);
42371
42373
  }
42372
42374
  const finalSnapshotId = context?.finalSnapshotIdentifier;
42373
42375
  await this.getClient().send(new DeleteDBClusterCommand$2({
@@ -42467,7 +42469,7 @@ var NeptuneProvider = class {
42467
42469
  }));
42468
42470
  this.logger.debug(`Disabled DeletionProtection on Neptune DBInstance ${logicalId} before delete`);
42469
42471
  } catch (disableError) {
42470
- if (!this.isNotFoundError(disableError, "DBInstanceNotFoundFault")) this.logger.debug(`Could not disable deletion protection for ${physicalId}: ${disableError instanceof Error ? disableError.message : String(disableError)}`);
42472
+ if (!this.isNotFoundError(disableError, "DBInstanceNotFoundFault")) this.logger.debug(`Could not disable deletion protection for ${physicalId}: ${describeAwsFailure(disableError).detail}`);
42471
42473
  }
42472
42474
  await this.getClient().send(new DeleteDBInstanceCommand$2({
42473
42475
  DBInstanceIdentifier: physicalId,
@@ -42712,7 +42714,7 @@ var NeptuneProvider = class {
42712
42714
  const tagsResp = await this.getClient().send(new ListTagsForResourceCommand$13({ ResourceName: arn }));
42713
42715
  result["Tags"] = normalizeAwsTagsToCfn(tagsResp.TagList);
42714
42716
  } catch (err) {
42715
- this.logger.debug(`Neptune ListTagsForResource(${arn}) failed: ${err instanceof Error ? err.message : String(err)}`);
42717
+ this.logger.debug(`Neptune ListTagsForResource(${arn}) failed: ${describeAwsFailure(err).detail}`);
42716
42718
  }
42717
42719
  }
42718
42720
  async importDBInstance(input) {
@@ -43038,7 +43040,7 @@ var Route53Provider = class {
43038
43040
  await this.getClient().send(new DeleteHostedZoneCommand({ Id: zoneId }));
43039
43041
  callerReferenceToken.release();
43040
43042
  } catch (deleteError) {
43041
- this.logger.warn(`Best-effort rollback DeleteHostedZone for ${zoneId} also failed: ${deleteError instanceof Error ? deleteError.message : String(deleteError)} — operator may need to clean up the orphan zone`);
43043
+ this.logger.warn(`Best-effort rollback DeleteHostedZone for ${zoneId} also failed: ${describeAwsFailure(deleteError).detail} — operator may need to clean up the orphan zone`);
43042
43044
  }
43043
43045
  const cause = uhfError instanceof Error ? uhfError : void 0;
43044
43046
  throw new ProvisioningError(`Failed to enable Accelerated Recovery on hosted zone ${logicalId} (${zoneId}): ${uhfError instanceof Error ? uhfError.message : String(uhfError)}`, resourceType, logicalId, zoneId, cause);
@@ -43568,7 +43570,7 @@ var Route53Provider = class {
43568
43570
  }));
43569
43571
  this.logger.debug(`Applied ${tags.length} tag(s) and removed ${removeTagKeys.length} tag(s) on hosted zone ${logicalId}`);
43570
43572
  } catch (error) {
43571
- const detail = error instanceof Error ? error.message : String(error);
43573
+ const detail = describeAwsFailure(error).detail;
43572
43574
  if (removeTagKeys.length > 0) throw new ProvisioningError(`Failed to remove tag(s) ${removeTagKeys.join(", ")} from hosted zone ${logicalId}: ${detail}. The removal will NOT be retried on the next deploy (state no longer records the tag), so it is reported instead of ignored.`, "AWS::Route53::HostedZone", logicalId, zoneId, error instanceof Error ? error : void 0);
43573
43575
  this.logger.warn(`Failed to apply tags to hosted zone ${logicalId}: ${detail}`);
43574
43576
  }
@@ -43631,7 +43633,7 @@ var Route53Provider = class {
43631
43633
  this.logger.debug(`Query logging config already exists for hosted zone ${logicalId}`);
43632
43634
  return;
43633
43635
  }
43634
- this.logger.warn(`Failed to apply query logging config to hosted zone ${logicalId}: ${error instanceof Error ? error.message : String(error)}`);
43636
+ this.logger.warn(`Failed to apply query logging config to hosted zone ${logicalId}: ${describeAwsFailure(error).detail}`);
43635
43637
  }
43636
43638
  }
43637
43639
  /**
@@ -43676,7 +43678,7 @@ var Route53Provider = class {
43676
43678
  }
43677
43679
  } catch (error) {
43678
43680
  if (error instanceof Error && (error.name === "NoSuchHostedZone" || error.name === "NoSuchQueryLoggingConfig")) return;
43679
- this.logger.warn(`Failed to delete query logging config for hosted zone ${logicalId}: ${error instanceof Error ? error.message : String(error)}`);
43681
+ this.logger.warn(`Failed to delete query logging config for hosted zone ${logicalId}: ${describeAwsFailure(error).detail}`);
43680
43682
  }
43681
43683
  }
43682
43684
  /**
@@ -43718,7 +43720,7 @@ var Route53Provider = class {
43718
43720
  }));
43719
43721
  }
43720
43722
  } catch (error) {
43721
- this.logger.warn(`Failed to sync VPC associations for hosted zone ${logicalId}: ${error instanceof Error ? error.message : String(error)}`);
43723
+ this.logger.warn(`Failed to sync VPC associations for hosted zone ${logicalId}: ${describeAwsFailure(error).detail}`);
43722
43724
  }
43723
43725
  }
43724
43726
  /**
@@ -43768,7 +43770,7 @@ var Route53Provider = class {
43768
43770
  const sawLaterName = zones.some((z) => normalizeRecordName(z.Name ?? "") !== normalizedName);
43769
43771
  absenceIsSound = !hostedZoneName.includes("\\") && (narrowing ? sawLaterName || response.IsTruncated !== true : zones.length > 0 || response.IsTruncated !== true);
43770
43772
  } catch (error) {
43771
- lookupErrorMessage = error instanceof Error ? error.message : String(error);
43773
+ lookupErrorMessage = describeAwsFailure(error).detail;
43772
43774
  lookupErrorCause = error instanceof Error ? error : void 0;
43773
43775
  this.logger.warn(`Failed to resolve HostedZoneName "${hostedZoneName}" for ${logicalId}: ${lookupErrorMessage}`);
43774
43776
  }
@@ -43811,7 +43813,7 @@ var Route53Provider = class {
43811
43813
  type
43812
43814
  };
43813
43815
  } catch (err) {
43814
- this.logger.debug(`Cannot resolve record-set identity for '${physicalId}': ${err instanceof Error ? err.message : String(err)}`);
43816
+ this.logger.debug(`Cannot resolve record-set identity for '${physicalId}': ${describeAwsFailure(err).detail}`);
43815
43817
  return;
43816
43818
  }
43817
43819
  }
@@ -43878,14 +43880,14 @@ var Route53Provider = class {
43878
43880
  }));
43879
43881
  result["HostedZoneTags"] = normalizeAwsTagsToCfn(tagsResp.ResourceTagSet?.Tags);
43880
43882
  } catch (err) {
43881
- this.logger.debug(`Route53 ListTagsForResource(${idTail}) failed: ${err instanceof Error ? err.message : String(err)}`);
43883
+ this.logger.debug(`Route53 ListTagsForResource(${idTail}) failed: ${describeAwsFailure(err).detail}`);
43882
43884
  }
43883
43885
  try {
43884
43886
  const qlc = (await this.getClient().send(new ListQueryLoggingConfigsCommand({ HostedZoneId: idTail }))).QueryLoggingConfigs?.[0];
43885
43887
  if (qlc?.CloudWatchLogsLogGroupArn) result["QueryLoggingConfig"] = { CloudWatchLogsLogGroupArn: qlc.CloudWatchLogsLogGroupArn };
43886
43888
  else result["QueryLoggingConfig"] = {};
43887
43889
  } catch (err) {
43888
- this.logger.debug(`Route53 ListQueryLoggingConfigs(${idTail}) failed: ${err instanceof Error ? err.message : String(err)}`);
43890
+ this.logger.debug(`Route53 ListQueryLoggingConfigs(${idTail}) failed: ${describeAwsFailure(err).detail}`);
43889
43891
  result["QueryLoggingConfig"] = {};
43890
43892
  }
43891
43893
  return result;
@@ -44101,7 +44103,7 @@ var Route53Provider = class {
44101
44103
  try {
44102
44104
  observed = await this.readRecordSet(compositeId);
44103
44105
  } catch (err) {
44104
- return adoptVerbatim(`verification failed: ${err instanceof Error ? err.message : String(err)}`);
44106
+ return adoptVerbatim(`verification failed: ${describeAwsFailure(err).detail}`);
44105
44107
  }
44106
44108
  if (!observed) return adoptVerbatim("the record was not found under the resolved hosted zone");
44107
44109
  return {
@@ -44157,7 +44159,7 @@ var Route53Provider = class {
44157
44159
  };
44158
44160
  } catch (error) {
44159
44161
  if (error instanceof Error && error.name === "NoSuchHostedZone") return null;
44160
- this.logger.warn(`Imported hosted zone ${zoneId} but could not read its NameServers: ${error instanceof Error ? error.message : String(error)}. The zone is adopted without them (any attributes already in state for this zone are kept). Re-run \`cdkd import --resource ${logicalId}=${zoneId} --force\` once the permission is granted, or make a template change that forces an UPDATE — a plain \`cdkd deploy\` does NOT heal the record, because an unchanged zone is NO_CHANGE and never calls update().`);
44162
+ this.logger.warn(`Imported hosted zone ${zoneId} but could not read its NameServers: ${describeAwsFailure(error).detail}. The zone is adopted without them (any attributes already in state for this zone are kept). Re-run \`cdkd import --resource ${logicalId}=${zoneId} --force\` once the permission is granted, or make a template change that forces an UPDATE — a plain \`cdkd deploy\` does NOT heal the record, because an unchanged zone is NO_CHANGE and never calls update().`);
44161
44163
  return {};
44162
44164
  }
44163
44165
  }
@@ -45132,7 +45134,7 @@ var CognitoUserPoolProvider = class {
45132
45134
  await this.getClient().send(new DeleteUserPoolCommand({ UserPoolId: createdUserPoolId }));
45133
45135
  this.logger.debug(`Rolled back partially-created Cognito User Pool ${createdUserPoolId}`);
45134
45136
  } catch (rollbackError) {
45135
- this.logger.warn(`Failed to roll back partially-created Cognito User Pool ${createdUserPoolId}: ${rollbackError instanceof Error ? rollbackError.message : String(rollbackError)}`);
45137
+ this.logger.warn(`Failed to roll back partially-created Cognito User Pool ${createdUserPoolId}: ${describeAwsFailure(rollbackError).detail}`);
45136
45138
  }
45137
45139
  const cause = error instanceof Error ? error : void 0;
45138
45140
  throw new ProvisioningError(`Failed to create Cognito User Pool ${logicalId}: ${error instanceof Error ? error.message : String(error)}`, resourceType, logicalId, poolName, cause);
@@ -45283,7 +45285,7 @@ var CognitoUserPoolProvider = class {
45283
45285
  failed: false
45284
45286
  } : { failed: false };
45285
45287
  } catch (error) {
45286
- this.logger.debug(`GetUserPoolMfaConfig failed for UserPool ${physicalId} (${error instanceof Error ? error.name : typeof error}): ${error instanceof Error ? error.message : String(error)}`);
45288
+ this.logger.debug(`GetUserPoolMfaConfig failed for UserPool ${physicalId} (${error instanceof Error ? error.name : typeof error}): ${describeAwsFailure(error).detail}`);
45287
45289
  return { failed: true };
45288
45290
  }
45289
45291
  }
@@ -45301,7 +45303,7 @@ var CognitoUserPoolProvider = class {
45301
45303
  for (let attempt = 1;; attempt++) try {
45302
45304
  return await fn();
45303
45305
  } catch (error) {
45304
- const msg = error instanceof Error ? error.message : String(error);
45306
+ const msg = describeAwsFailure(error).detail;
45305
45307
  if (!((error instanceof Error ? error.name : "") === "ConcurrentModificationException" || /concurrent modification|please retry|try again|in progress/i.test(msg)) || attempt >= maxAttempts) throw error;
45306
45308
  const delayMs = Math.min(1e3 * 2 ** (attempt - 1), 4e3);
45307
45309
  this.logger.debug(`Transient error on "${label}" (attempt ${attempt}/${maxAttempts}): ${msg} — retrying in ${delayMs}ms`);
@@ -45559,7 +45561,7 @@ var CognitoUserPoolProvider = class {
45559
45561
  DeletionProtection: "INACTIVE"
45560
45562
  }));
45561
45563
  } catch (flipError) {
45562
- this.logger.debug(`Could not disable DeletionProtection for ${physicalId}: ${flipError instanceof Error ? flipError.message : String(flipError)}`);
45564
+ this.logger.debug(`Could not disable DeletionProtection for ${physicalId}: ${describeAwsFailure(flipError).detail}`);
45563
45565
  }
45564
45566
  }
45565
45567
  }
@@ -45646,7 +45648,7 @@ var CognitoUserPoolProvider = class {
45646
45648
  result["WebAuthnRelyingPartyID"] = mfa.WebAuthnConfiguration?.RelyingPartyId ?? "";
45647
45649
  result["WebAuthnUserVerification"] = mfa.WebAuthnConfiguration?.UserVerification ?? "";
45648
45650
  } catch (mfaErr) {
45649
- this.logger.debug(`GetUserPoolMfaConfig failed for ${physicalId}, skipping MFA-derived drift keys: ${mfaErr instanceof Error ? mfaErr.message : String(mfaErr)}`);
45651
+ this.logger.debug(`GetUserPoolMfaConfig failed for ${physicalId}, skipping MFA-derived drift keys: ${describeAwsFailure(mfaErr).detail}`);
45650
45652
  }
45651
45653
  return result;
45652
45654
  }
@@ -46159,7 +46161,7 @@ var ElastiCacheProvider = class {
46159
46161
  const tagsResp = await this.getClient().send(new ListTagsForResourceCommand$7({ ResourceName: arn }));
46160
46162
  result["Tags"] = normalizeAwsTagsToCfn(tagsResp.TagList);
46161
46163
  } catch (err) {
46162
- this.logger.debug(`ElastiCache ListTagsForResource(${arn}) failed: ${err instanceof Error ? err.message : String(err)}`);
46164
+ this.logger.debug(`ElastiCache ListTagsForResource(${arn}) failed: ${describeAwsFailure(err).detail}`);
46163
46165
  }
46164
46166
  }
46165
46167
  /**
@@ -46598,7 +46600,7 @@ var ServiceDiscoveryProvider = class ServiceDiscoveryProvider {
46598
46600
  arn = nsResp.Namespace?.Arn;
46599
46601
  hostedZoneId = nsResp.Namespace?.Properties?.DnsProperties?.HostedZoneId;
46600
46602
  } catch (err) {
46601
- this.logger.debug(`GetNamespace(${namespaceId}) after create failed: ${err instanceof Error ? err.message : String(err)}`);
46603
+ this.logger.debug(`GetNamespace(${namespaceId}) after create failed: ${describeAwsFailure(err).detail}`);
46602
46604
  }
46603
46605
  if (!arn) arn = await this.buildNamespaceArn(namespaceId);
46604
46606
  this.logger.debug(`Successfully created public DNS namespace ${logicalId}: ${namespaceId}`);
@@ -46874,7 +46876,7 @@ var ServiceDiscoveryProvider = class ServiceDiscoveryProvider {
46874
46876
  const resp = await this.getClient().send(new GetNamespaceCommand({ Id: namespaceId }));
46875
46877
  if (resp.Namespace?.Arn) return resp.Namespace.Arn;
46876
46878
  } catch (err) {
46877
- this.logger.debug(`GetNamespace(${namespaceId}) failed while resolving ARN: ${err instanceof Error ? err.message : String(err)}`);
46879
+ this.logger.debug(`GetNamespace(${namespaceId}) failed while resolving ARN: ${describeAwsFailure(err).detail}`);
46878
46880
  }
46879
46881
  return this.buildNamespaceArn(namespaceId);
46880
46882
  }
@@ -47098,7 +47100,7 @@ var ServiceDiscoveryProvider = class ServiceDiscoveryProvider {
47098
47100
  try {
47099
47101
  result["ServiceAttributes"] = (await this.getClient().send(new GetServiceAttributesCommand({ ServiceId: physicalId }))).ServiceAttributes?.Attributes ?? {};
47100
47102
  } catch (err) {
47101
- this.logger.debug(`ServiceDiscovery GetServiceAttributes(${physicalId}) failed: ${err instanceof Error ? err.message : String(err)}`);
47103
+ this.logger.debug(`ServiceDiscovery GetServiceAttributes(${physicalId}) failed: ${describeAwsFailure(err).detail}`);
47102
47104
  }
47103
47105
  if (svc.Arn) await this.attachTags(result, svc.Arn);
47104
47106
  return result;
@@ -47126,7 +47128,7 @@ var ServiceDiscoveryProvider = class ServiceDiscoveryProvider {
47126
47128
  const tagsResp = await this.getClient().send(new ListTagsForResourceCommand$14({ ResourceARN: arn }));
47127
47129
  result["Tags"] = normalizeAwsTagsToCfn(tagsResp.Tags);
47128
47130
  } catch (err) {
47129
- this.logger.debug(`ServiceDiscovery ListTagsForResource(${arn}) failed: ${err instanceof Error ? err.message : String(err)}`);
47131
+ this.logger.debug(`ServiceDiscovery ListTagsForResource(${arn}) failed: ${describeAwsFailure(err).detail}`);
47130
47132
  }
47131
47133
  }
47132
47134
  async import(input) {
@@ -47396,7 +47398,7 @@ var AppSyncProvider = class {
47396
47398
  try {
47397
47399
  return await this.buildAppSyncArn(suffix);
47398
47400
  } catch (error) {
47399
- this.logger.warn(`Created ${logicalId} (${physicalId}) but could not build its ARN attribute: ${error instanceof Error ? error.message : String(error)}. Ref will resolve to the compound physical id until the next update.`);
47401
+ this.logger.warn(`Created ${logicalId} (${physicalId}) but could not build its ARN attribute: ${describeAwsFailure(error).detail}. Ref will resolve to the compound physical id until the next update.`);
47400
47402
  return;
47401
47403
  }
47402
47404
  }
@@ -47437,7 +47439,7 @@ var AppSyncProvider = class {
47437
47439
  return await this.buildAppSyncArn(suffix, regionOverride);
47438
47440
  } catch (error) {
47439
47441
  if (!omitArnOnFailure) throw error;
47440
- this.logger.warn(`Imported ${resourceType} (${physicalId}) but its ARN attribute was NOT recorded: ${error instanceof Error ? error.message : String(error)}. Ref will resolve to the compound physical id, and Fn::GetAtt on the ARN will fail, until the resource's next update heals the record.`);
47442
+ this.logger.warn(`Imported ${resourceType} (${physicalId}) but its ARN attribute was NOT recorded: ${describeAwsFailure(error).detail}. Ref will resolve to the compound physical id, and Fn::GetAtt on the ARN will fail, until the resource's next update heals the record.`);
47441
47443
  return;
47442
47444
  }
47443
47445
  };
@@ -47480,7 +47482,7 @@ var AppSyncProvider = class {
47480
47482
  try {
47481
47483
  attributes = await this.childRefAttributes(resourceType, physicalId);
47482
47484
  } catch (error) {
47483
- this.logger.warn(`Updated ${resourceType} (${physicalId}) but could not rebuild its ARN attribute: ${error instanceof Error ? error.message : String(error)}. The previously recorded attributes are kept.`);
47485
+ this.logger.warn(`Updated ${resourceType} (${physicalId}) but could not rebuild its ARN attribute: ${describeAwsFailure(error).detail}. The previously recorded attributes are kept.`);
47484
47486
  }
47485
47487
  return {
47486
47488
  physicalId,
@@ -47525,7 +47527,7 @@ var AppSyncProvider = class {
47525
47527
  try {
47526
47528
  return await this.childRefAttributes(resourceType, physicalId, region, true) ?? {};
47527
47529
  } catch (error) {
47528
- this.logger.warn(`Imported ${resourceType} (${physicalId}) but could not build its ARN attribute: ${error instanceof Error ? error.message : String(error)}. Ref will resolve to the compound physical id, and Fn::GetAtt on the ARN will fail, until the resource's next update heals the record.`);
47530
+ this.logger.warn(`Imported ${resourceType} (${physicalId}) but could not build its ARN attribute: ${describeAwsFailure(error).detail}. Ref will resolve to the compound physical id, and Fn::GetAtt on the ARN will fail, until the resource's next update heals the record.`);
47529
47531
  return {};
47530
47532
  }
47531
47533
  }
@@ -47992,7 +47994,7 @@ var AppSyncProvider = class {
47992
47994
  try {
47993
47995
  entries = requireConfigArray(value, "AWS::AppSync::GraphQLApi AdditionalAuthenticationProviders");
47994
47996
  } catch (error) {
47995
- const message = error instanceof Error ? error.message : String(error);
47997
+ const message = describeAwsFailure(error).detail;
47996
47998
  if (options?.onUnusable) {
47997
47999
  options.onUnusable(message);
47998
48000
  return;
@@ -48087,7 +48089,7 @@ var AppSyncProvider = class {
48087
48089
  desired = this.asObject(properties["EnvironmentVariables"], "EnvironmentVariables", { logicalId });
48088
48090
  } catch (error) {
48089
48091
  if (!isUpdate && !replayingState) throw error;
48090
- this.logger.warn(`AppSync GraphqlApi ${logicalId}: ${error instanceof Error ? error.message : String(error)} — leaving the live environment variables untouched`);
48092
+ this.logger.warn(`AppSync GraphqlApi ${logicalId}: ${describeAwsFailure(error).detail} — leaving the live environment variables untouched`);
48091
48093
  return;
48092
48094
  }
48093
48095
  let previous;
@@ -48396,7 +48398,7 @@ var AppSyncProvider = class {
48396
48398
  await this.getClient().send(new DeleteGraphqlApiCommand({ apiId: createdApiId }));
48397
48399
  this.logger.debug(`Rolled back partially-created GraphQL API ${createdApiId}`);
48398
48400
  } catch (rollbackError) {
48399
- this.logger.warn(`Failed to roll back partially-created GraphQL API ${createdApiId}: ${rollbackError instanceof Error ? rollbackError.message : String(rollbackError)}`);
48401
+ this.logger.warn(`Failed to roll back partially-created GraphQL API ${createdApiId}: ${describeAwsFailure(rollbackError).detail}`);
48400
48402
  }
48401
48403
  const cause = error instanceof Error ? error : void 0;
48402
48404
  throw new ProvisioningError(`Failed to create GraphQL API ${logicalId}: ${error instanceof Error ? error.message : String(error)}`, resourceType, logicalId, void 0, cause);
@@ -48703,7 +48705,7 @@ var AppSyncProvider = class {
48703
48705
  try {
48704
48706
  return print(parse$1(sdl));
48705
48707
  } catch (err) {
48706
- this.logger.debug(`Failed to parse ${source} SDL via graphql-js (falling back to raw): ${err instanceof Error ? err.message : String(err)}`);
48708
+ this.logger.debug(`Failed to parse ${source} SDL via graphql-js (falling back to raw): ${describeAwsFailure(err).detail}`);
48707
48709
  return sdl;
48708
48710
  }
48709
48711
  }
@@ -48782,7 +48784,7 @@ var AppSyncProvider = class {
48782
48784
  const envResp = await this.getClient().send(new GetGraphqlApiEnvironmentVariablesCommand({ apiId: physicalId }));
48783
48785
  if (envResp.environmentVariables !== void 0) result["EnvironmentVariables"] = envResp.environmentVariables;
48784
48786
  } catch (err) {
48785
- this.logger.warn(`Could not read AppSync GraphqlApi ${physicalId} environment variables (drift on that property will not be reported): ${err instanceof Error ? err.message : String(err)}`);
48787
+ this.logger.warn(`Could not read AppSync GraphqlApi ${physicalId} environment variables (drift on that property will not be reported): ${describeAwsFailure(err).detail}`);
48786
48788
  }
48787
48789
  return result;
48788
48790
  }
@@ -50158,7 +50160,7 @@ var GlueWorkflowProvider = class {
50158
50160
  const tagResp = await this.getClient().send(new GetTagsCommand({ ResourceArn: arn }));
50159
50161
  tags = normalizeAwsTagsToCfn(tagResp.Tags);
50160
50162
  } catch (err) {
50161
- this.logger.debug(`GetTags failed for Glue Workflow ${physicalId}: ${err instanceof Error ? err.message : String(err)}`);
50163
+ this.logger.debug(`GetTags failed for Glue Workflow ${physicalId}: ${describeAwsFailure(err).detail}`);
50162
50164
  }
50163
50165
  result["Tags"] = tags;
50164
50166
  return result;
@@ -50525,7 +50527,7 @@ async function fetchGlueTags(client, stsClient, resource, name, accountId, logge
50525
50527
  const resp = await client.send(new GetTagsCommand({ ResourceArn: arn }));
50526
50528
  return normalizeAwsTagsToCfn(resp.Tags);
50527
50529
  } catch (err) {
50528
- logger.debug(`GetTags failed for ${resource}/${name}: ${err instanceof Error ? err.message : String(err)}`);
50530
+ logger.debug(`GetTags failed for ${resource}/${name}: ${describeAwsFailure(err).detail}`);
50529
50531
  return [];
50530
50532
  }
50531
50533
  }
@@ -51058,7 +51060,7 @@ var GlueCrawlerProvider = class {
51058
51060
  try {
51059
51061
  await this.getClient().send(new StopCrawlerCommand({ Name: physicalId }));
51060
51062
  } catch (err) {
51061
- this.logger.debug(`StopCrawler for ${physicalId} returned ${err instanceof Error ? err.name : String(err)}; continuing to wait`);
51063
+ this.logger.debug(`StopCrawler for ${physicalId} returned ${err instanceof Error ? err.name : safeStringify(err)}; continuing to wait`);
51062
51064
  }
51063
51065
  for (let attempt = 0; attempt < CRAWLER_STOP_MAX_ATTEMPTS; attempt++) {
51064
51066
  try {
@@ -51493,7 +51495,7 @@ var GlueTriggerProvider = class {
51493
51495
  await this.waitForTriggerDeactivated(physicalId);
51494
51496
  }
51495
51497
  } catch (err) {
51496
- if (!(err instanceof EntityNotFoundException)) this.logger.debug(`GetTrigger pre-check failed for ${physicalId}; continuing anyway: ${err instanceof Error ? err.message : String(err)}`);
51498
+ if (!(err instanceof EntityNotFoundException)) this.logger.debug(`GetTrigger pre-check failed for ${physicalId}; continuing anyway: ${describeAwsFailure(err).detail}`);
51497
51499
  }
51498
51500
  const update = {
51499
51501
  ...properties["Description"] !== void 0 && { Description: properties["Description"] },
@@ -51556,7 +51558,7 @@ var GlueTriggerProvider = class {
51556
51558
  await this.waitForTriggerDeactivated(physicalId);
51557
51559
  }
51558
51560
  } catch (err) {
51559
- if (!(err instanceof EntityNotFoundException)) this.logger.debug(`GetTrigger pre-delete check failed for ${physicalId}; continuing: ${err instanceof Error ? err.message : String(err)}`);
51561
+ if (!(err instanceof EntityNotFoundException)) this.logger.debug(`GetTrigger pre-delete check failed for ${physicalId}; continuing: ${describeAwsFailure(err).detail}`);
51560
51562
  }
51561
51563
  await this.getClient().send(new DeleteTriggerCommand({ Name: physicalId }));
51562
51564
  } catch (error) {
@@ -53115,7 +53117,7 @@ var KinesisStreamProvider = class {
53115
53117
  result["Tags"] = normalizeAwsTagsToCfn(tagsResp.Tags);
53116
53118
  } catch (err) {
53117
53119
  if (err instanceof ResourceNotFoundException$10) return void 0;
53118
- this.logger.debug(`Kinesis ListTagsForStream(${physicalId}) failed: ${err instanceof Error ? err.message : String(err)}`);
53120
+ this.logger.debug(`Kinesis ListTagsForStream(${physicalId}) failed: ${describeAwsFailure(err).detail}`);
53119
53121
  }
53120
53122
  return result;
53121
53123
  }
@@ -53296,7 +53298,7 @@ var KinesisStreamConsumerProvider = class {
53296
53298
  StreamARN: desc.StreamARN
53297
53299
  };
53298
53300
  } catch (err) {
53299
- this.logger.debug(`DescribeStreamConsumer(${physicalId}) failed: ${err instanceof Error ? err.message : String(err)}`);
53301
+ this.logger.debug(`DescribeStreamConsumer(${physicalId}) failed: ${describeAwsFailure(err).detail}`);
53300
53302
  }
53301
53303
  return {
53302
53304
  physicalId,
@@ -53378,7 +53380,7 @@ var KinesisStreamConsumerProvider = class {
53378
53380
  result["Tags"] = normalizeAwsTagsToCfn(tagsResp.Tags);
53379
53381
  } catch (err) {
53380
53382
  if (err instanceof ResourceNotFoundException$10) return void 0;
53381
- this.logger.debug(`ListTagsForResource(${physicalId}) failed: ${err instanceof Error ? err.message : String(err)}`);
53383
+ this.logger.debug(`ListTagsForResource(${physicalId}) failed: ${describeAwsFailure(err).detail}`);
53382
53384
  result["Tags"] = [];
53383
53385
  }
53384
53386
  return result;
@@ -53969,7 +53971,7 @@ var EFSProvider = class {
53969
53971
  await this.getClient().send(new DeleteFileSystemCommand({ FileSystemId: fileSystemId }));
53970
53972
  this.logger.debug(`Rolled back partially-created EFS FileSystem ${fileSystemId}`);
53971
53973
  } catch (cleanupError) {
53972
- this.logger.warn(`Failed to roll back partially-created EFS FileSystem ${fileSystemId}: ${cleanupError instanceof Error ? cleanupError.message : String(cleanupError)}`);
53974
+ this.logger.warn(`Failed to roll back partially-created EFS FileSystem ${fileSystemId}: ${describeAwsFailure(cleanupError).detail}`);
53973
53975
  }
53974
53976
  if (error instanceof ProvisioningError) throw error;
53975
53977
  const cause = error instanceof Error ? error : void 0;
@@ -54051,7 +54053,7 @@ var EFSProvider = class {
54051
54053
  for (let attempt = 1;; attempt++) try {
54052
54054
  return await op();
54053
54055
  } catch (error) {
54054
- const msg = error instanceof Error ? error.message : String(error);
54056
+ const msg = describeAwsFailure(error).detail;
54055
54057
  const name = error instanceof Error ? error.name : "";
54056
54058
  if (!(/in progress|please retry|incorrect file system life ?cycle state|being (updated|modified)|try again/i.test(msg) || name === "IncorrectFileSystemLifeCycleState" || name === "ConflictException" || name === "ThrottlingException") || attempt >= maxAttempts) throw error;
54057
54059
  this.logger.debug(`Transient error on "${label}" (attempt ${attempt}/${maxAttempts}): ${msg} — retrying in ${delayMs}ms`);
@@ -54793,7 +54795,7 @@ var FSxFileSystemProvider = class {
54793
54795
  await this.getClient().send(new DeleteFileSystemCommand$1({ FileSystemId: fileSystemId }));
54794
54796
  this.logger.warn(`Rolled back partially-created FSx FileSystem ${fileSystemId}`);
54795
54797
  } catch (cleanupError) {
54796
- this.logger.warn(`Failed to roll back partially-created FSx FileSystem ${fileSystemId}: ${cleanupError instanceof Error ? cleanupError.message : String(cleanupError)} — delete it manually to stop billing`);
54798
+ this.logger.warn(`Failed to roll back partially-created FSx FileSystem ${fileSystemId}: ${describeAwsFailure(cleanupError).detail} — delete it manually to stop billing`);
54797
54799
  }
54798
54800
  if (error instanceof ProvisioningError) throw error;
54799
54801
  const cause = error instanceof Error ? error : void 0;
@@ -55014,7 +55016,7 @@ var FSxFileSystemProvider = class {
55014
55016
  if (!updatedFs) try {
55015
55017
  updatedFs = (await this.getClient().send(new DescribeFileSystemsCommand$1({ FileSystemIds: [physicalId] }))).FileSystems?.[0];
55016
55018
  } catch (describeError) {
55017
- this.logger.debug(`Post-update attribute refresh for ${physicalId} failed (returning without attributes): ${describeError instanceof Error ? describeError.message : String(describeError)}`);
55019
+ this.logger.debug(`Post-update attribute refresh for ${physicalId} failed (returning without attributes): ${describeAwsFailure(describeError).detail}`);
55018
55020
  }
55019
55021
  this.logger.debug(`Successfully updated FSx FileSystem ${logicalId}`);
55020
55022
  return {
@@ -55260,7 +55262,7 @@ var FSxFileSystemProvider = class {
55260
55262
  return response.FileSystems?.[0];
55261
55263
  } catch (error) {
55262
55264
  const name = error instanceof Error ? error.name : "";
55263
- const msg = error instanceof Error ? error.message : String(error);
55265
+ const msg = describeAwsFailure(error).detail;
55264
55266
  if ((name === "ThrottlingException" || name === "ServiceLimitExceeded" || name === "InternalServerError" || name === "TimeoutError" || /rate exceeded|too many requests|timed? ?out|ECONNRESET|EPIPE|socket hang up/i.test(msg)) && transientState.count < maxConsecutiveTransient) {
55265
55267
  transientState.count += 1;
55266
55268
  this.logger.debug(`Transient DescribeFileSystems error while polling ${fileSystemId} (${transientState.count}/${maxConsecutiveTransient}): ${msg} — retrying`);
@@ -55919,7 +55921,7 @@ var EMRClusterProvider = class {
55919
55921
  await this.getClient().send(new TerminateJobFlowsCommand({ JobFlowIds: [clusterId] }));
55920
55922
  this.logger.warn(`Rolled back partially-created EMR Cluster ${clusterId}`);
55921
55923
  } catch (cleanupError) {
55922
- this.logger.warn(`Failed to roll back partially-created EMR Cluster ${clusterId}: ${cleanupError instanceof Error ? cleanupError.message : String(cleanupError)} — terminate it manually to stop billing`);
55924
+ this.logger.warn(`Failed to roll back partially-created EMR Cluster ${clusterId}: ${describeAwsFailure(cleanupError).detail} — terminate it manually to stop billing`);
55923
55925
  }
55924
55926
  if (error instanceof ProvisioningError) throw error;
55925
55927
  const cause = error instanceof Error ? error : void 0;
@@ -56097,7 +56099,7 @@ var EMRClusterProvider = class {
56097
56099
  try {
56098
56100
  cluster = (await this.getClient().send(new DescribeClusterCommand({ ClusterId: physicalId }))).Cluster;
56099
56101
  } catch (describeError) {
56100
- this.logger.debug(`Post-update attribute refresh for ${physicalId} failed (returning without attributes): ${describeError instanceof Error ? describeError.message : String(describeError)}`);
56102
+ this.logger.debug(`Post-update attribute refresh for ${physicalId} failed (returning without attributes): ${describeAwsFailure(describeError).detail}`);
56101
56103
  }
56102
56104
  this.logger.debug(`Successfully updated EMR Cluster ${logicalId}`);
56103
56105
  return {
@@ -56190,7 +56192,7 @@ var EMRClusterProvider = class {
56190
56192
  return response.Cluster;
56191
56193
  } catch (error) {
56192
56194
  const name = error instanceof Error ? error.name : "";
56193
- const msg = error instanceof Error ? error.message : String(error);
56195
+ const msg = describeAwsFailure(error).detail;
56194
56196
  if ((name === "ThrottlingException" || name === "InternalServerException" || name === "InternalServerError" || name === "TimeoutError" || /rate exceeded|too many requests|throttl|timed? ?out|ECONNRESET|EPIPE|socket hang up/i.test(msg)) && transientState.count < maxConsecutiveTransient) {
56195
56197
  transientState.count += 1;
56196
56198
  this.logger.debug(`Transient DescribeCluster error while polling ${clusterId} (${transientState.count}/${maxConsecutiveTransient}): ${msg} — retrying`);
@@ -56737,7 +56739,7 @@ var EMRInstanceGroupConfigProvider = class {
56737
56739
  const clientRegion = await this.getClient().config.region();
56738
56740
  assertRegionMatch(clientRegion, context?.expectedRegion, resourceType, logicalId, physicalId);
56739
56741
  this.logger.debug(`EMR instance group ${physicalId} scale-to-0 skipped (cluster/group gone): ${error.message}`);
56740
- } else this.logger.warn(`Best-effort scale-to-0 of EMR instance group ${physicalId} failed: ${error instanceof Error ? error.message : String(error)} — its instances are released when the parent cluster terminates`);
56742
+ } else this.logger.warn(`Best-effort scale-to-0 of EMR instance group ${physicalId} failed: ${describeAwsFailure(error).detail} — its instances are released when the parent cluster terminates`);
56741
56743
  }
56742
56744
  return;
56743
56745
  }
@@ -56824,7 +56826,7 @@ var EMRInstanceGroupConfigProvider = class {
56824
56826
  return;
56825
56827
  } catch (error) {
56826
56828
  const name = error instanceof Error ? error.name : "";
56827
- const msg = error instanceof Error ? error.message : String(error);
56829
+ const msg = describeAwsFailure(error).detail;
56828
56830
  if ((name === "ThrottlingException" || name === "InternalServerException" || name === "InternalServerError" || name === "TimeoutError" || /rate exceeded|too many requests|throttl|timed? ?out|ECONNRESET|EPIPE|socket hang up/i.test(msg)) && transientState.count < maxConsecutiveTransient) {
56829
56831
  transientState.count += 1;
56830
56832
  this.logger.debug(`Transient ListInstanceGroups error while polling ${groupId} (${transientState.count}/${maxConsecutiveTransient}): ${msg} — retrying`);
@@ -57051,7 +57053,7 @@ var EMRInstanceFleetConfigProvider = class {
57051
57053
  const clientRegion = await this.getClient().config.region();
57052
57054
  assertRegionMatch(clientRegion, context?.expectedRegion, resourceType, logicalId, physicalId);
57053
57055
  this.logger.debug(`EMR instance fleet ${physicalId} scale-to-0 skipped (cluster/fleet gone): ${error.message}`);
57054
- } else this.logger.warn(`Best-effort scale-to-0 of EMR instance fleet ${physicalId} failed: ${error instanceof Error ? error.message : String(error)} — its instances are released when the parent cluster terminates`);
57056
+ } else this.logger.warn(`Best-effort scale-to-0 of EMR instance fleet ${physicalId} failed: ${describeAwsFailure(error).detail} — its instances are released when the parent cluster terminates`);
57055
57057
  }
57056
57058
  return;
57057
57059
  }
@@ -57178,7 +57180,7 @@ var EMRInstanceFleetConfigProvider = class {
57178
57180
  return;
57179
57181
  } catch (error) {
57180
57182
  const name = error instanceof Error ? error.name : "";
57181
- const msg = error instanceof Error ? error.message : String(error);
57183
+ const msg = describeAwsFailure(error).detail;
57182
57184
  if ((name === "ThrottlingException" || name === "InternalServerException" || name === "InternalServerError" || name === "TimeoutError" || /rate exceeded|too many requests|throttl|timed? ?out|ECONNRESET|EPIPE|socket hang up/i.test(msg)) && transientState.count < maxConsecutiveTransient) {
57183
57185
  transientState.count += 1;
57184
57186
  this.logger.debug(`Transient ListInstanceFleets error while polling ${fleetId} (${transientState.count}/${maxConsecutiveTransient}): ${msg} — retrying`);
@@ -58232,7 +58234,7 @@ var FirehoseProvider = class {
58232
58234
  result["Tags"] = normalizeAwsTagsToCfn(tagsResp.Tags);
58233
58235
  } catch (err) {
58234
58236
  if (err instanceof ResourceNotFoundException$12) return void 0;
58235
- this.logger.debug(`Firehose ListTagsForDeliveryStream(${physicalId}) failed: ${err instanceof Error ? err.message : String(err)}`);
58237
+ this.logger.debug(`Firehose ListTagsForDeliveryStream(${physicalId}) failed: ${describeAwsFailure(err).detail}`);
58236
58238
  result["Tags"] = [];
58237
58239
  }
58238
58240
  return result;
@@ -58696,7 +58698,7 @@ var CloudTrailProvider = class {
58696
58698
  newEventSelectors = requireConfigArray(rawEventSelectors, "AWS::CloudTrail::Trail EventSelectors");
58697
58699
  } catch (error) {
58698
58700
  eventSelectorsUnusable = true;
58699
- this.logger.warn(`${error instanceof Error ? error.message : String(error)} The trail's existing event selectors are left untouched for this update rather than reset to the AWS default.`);
58701
+ this.logger.warn(`${describeAwsFailure(error).detail} The trail's existing event selectors are left untouched for this update rather than reset to the AWS default.`);
58700
58702
  }
58701
58703
  const oldEventSelectors = previousProperties["EventSelectors"];
58702
58704
  if (!eventSelectorsUnusable && JSON.stringify(newEventSelectors) !== JSON.stringify(oldEventSelectors)) {
@@ -58709,7 +58711,7 @@ var CloudTrailProvider = class {
58709
58711
  EventSelectors: [...eventSelectorsToSend]
58710
58712
  }));
58711
58713
  } catch (error) {
58712
- const message = error instanceof Error ? error.message : String(error);
58714
+ const message = describeAwsFailure(error).detail;
58713
58715
  if (!isRemoval || !/advanced[\s-]*event[\s-]*selector/i.test(message)) throw error;
58714
58716
  this.logger.warn(`CloudTrail Trail ${logicalId}: skipping the EventSelectors reset — the trail is using AdvancedEventSelectors, which AWS manages through a separate API, so there are no basic event selectors to clear (${message})`);
58715
58717
  }
@@ -58878,7 +58880,7 @@ var CloudTrailProvider = class {
58878
58880
  const tagsResp = await this.getClient().send(new ListTagsCommand$2({ ResourceIdList: [trail.TrailARN] }));
58879
58881
  tags = normalizeAwsTagsToCfn(tagsResp.ResourceTagList?.[0]?.TagsList);
58880
58882
  } catch (err) {
58881
- this.logger.debug(`CloudTrail ListTags(${trail.TrailARN}) failed: ${err instanceof Error ? err.message : String(err)}`);
58883
+ this.logger.debug(`CloudTrail ListTags(${trail.TrailARN}) failed: ${describeAwsFailure(err).detail}`);
58882
58884
  }
58883
58885
  result["Tags"] = tags;
58884
58886
  return result;
@@ -59886,7 +59888,7 @@ var CodeCommitRepositoryProvider = class {
59886
59888
  try {
59887
59889
  await this.getClient().send(new DeleteRepositoryCommand$1({ repositoryName }));
59888
59890
  } catch (cleanupError) {
59889
- this.logger.warn(`Failed to clean up CodeCommit Repository ${repositoryName} after a post-create failure: ${cleanupError instanceof Error ? cleanupError.message : String(cleanupError)}`);
59891
+ this.logger.warn(`Failed to clean up CodeCommit Repository ${repositoryName} after a post-create failure: ${describeAwsFailure(cleanupError).detail}`);
59890
59892
  }
59891
59893
  }
59892
59894
  /**
@@ -60067,7 +60069,7 @@ var DLMLifecyclePolicyProvider = class {
60067
60069
  try {
60068
60070
  arn = await this.fetchPolicyArn(response.PolicyId);
60069
60071
  } catch (err) {
60070
- this.logger.warn(`Created DLM Lifecycle Policy ${response.PolicyId} but could not fetch its ARN: ${err instanceof Error ? err.message : String(err)}`);
60072
+ this.logger.warn(`Created DLM Lifecycle Policy ${response.PolicyId} but could not fetch its ARN: ${describeAwsFailure(err).detail}`);
60071
60073
  }
60072
60074
  this.logger.debug(`Successfully created DLM Lifecycle Policy ${logicalId}: ${response.PolicyId}`);
60073
60075
  return {
@@ -60436,7 +60438,7 @@ var S3VectorsProvider = class {
60436
60438
  const tagsResp = await this.getClient().send(new ListTagsForResourceCommand$17({ resourceArn: bucket.vectorBucketArn }));
60437
60439
  result["Tags"] = normalizeAwsTagsToCfn(tagsResp.tags);
60438
60440
  } catch (err) {
60439
- this.logger.debug(`S3Vectors ListTagsForResource(${bucket.vectorBucketArn}) failed: ${err instanceof Error ? err.message : String(err)}`);
60441
+ this.logger.debug(`S3Vectors ListTagsForResource(${bucket.vectorBucketArn}) failed: ${describeAwsFailure(err).detail}`);
60440
60442
  result["Tags"] = [];
60441
60443
  }
60442
60444
  else this.logger.debug(`S3Vectors GetVectorBucket(${physicalId}) returned no vectorBucketArn; skipping Tags readback`);
@@ -60531,7 +60533,7 @@ var S3DirectoryBucketProvider = class {
60531
60533
  return azId;
60532
60534
  }
60533
60535
  } catch (error) {
60534
- this.logger.debug(`Failed to resolve AZ ID for ${azName}: ${error instanceof Error ? error.message : String(error)}`);
60536
+ this.logger.debug(`Failed to resolve AZ ID for ${azName}: ${describeAwsFailure(error).detail}`);
60535
60537
  }
60536
60538
  return azName;
60537
60539
  }
@@ -60717,7 +60719,7 @@ var S3DirectoryBucketProvider = class {
60717
60719
  this.logger.debug(`Successfully deleted S3 Express Directory Bucket ${logicalId}`);
60718
60720
  return;
60719
60721
  } catch (error) {
60720
- const msg = error instanceof Error ? error.message : String(error);
60722
+ const msg = describeAwsFailure(error).detail;
60721
60723
  if (msg.includes("not empty") || msg.includes("BucketNotEmpty")) {
60722
60724
  if (!allowAutoEmpty) throw new Error(`bucket ${bucketName} is not empty. Matching CloudFormation, cdkd does not delete a non-empty directory bucket without an explicit opt-in. Delete all objects first (e.g. aws s3 rm s3://${bucketName} --recursive) and destroy again.`);
60723
60725
  this.logger.info(`Directory bucket ${bucketName} not empty (attempt ${attempt}/${maxAttempts}), emptying (auto-delete opt-in present)...`);
@@ -61257,7 +61259,7 @@ var S3TablesProvider = class {
61257
61259
  try {
61258
61260
  resolved = await this.resolveTableParts(physicalId);
61259
61261
  } catch (err) {
61260
- this.logger.warn(`S3 Tables Table ${physicalId}: could not resolve its identity for drift (${err instanceof Error ? err.message : String(err)}); reporting drift as unknown.`);
61262
+ this.logger.warn(`S3 Tables Table ${physicalId}: could not resolve its identity for drift (${describeAwsFailure(err).detail}); reporting drift as unknown.`);
61261
61263
  return;
61262
61264
  }
61263
61265
  if (resolved === "not-found" || resolved === "unparseable") return void 0;
@@ -61596,7 +61598,7 @@ var S3TablesProvider = class {
61596
61598
  });
61597
61599
  return out;
61598
61600
  } catch (err) {
61599
- this.logger.debug(`readTagsBestEffort: ListTagsForResource failed for ${resourceArn}: ${err instanceof Error ? err.message : String(err)} — emitting Tags: []`);
61601
+ this.logger.debug(`readTagsBestEffort: ListTagsForResource failed for ${resourceArn}: ${describeAwsFailure(err).detail} — emitting Tags: []`);
61600
61602
  return [];
61601
61603
  }
61602
61604
  }
@@ -63513,7 +63515,7 @@ var ACMCertificateProvider = class {
63513
63515
  idempotencyToken.release();
63514
63516
  return;
63515
63517
  }
63516
- const detail = cleanupError instanceof Error ? cleanupError.message : String(cleanupError);
63518
+ const detail = describeAwsFailure(cleanupError).detail;
63517
63519
  this.logger.warn(`Could not delete the ACM certificate ${certificateArn} that the failed create of ${logicalId} requested: ${detail}`);
63518
63520
  return `The certificate ${certificateArn} this attempt created could NOT be deleted, and cdkd is not tracking it -- retire it with \`aws acm delete-certificate --certificate-arn ${certificateArn} --region ${this.regionOfArn(certificateArn)}\` (the reason is in the warning above).`;
63519
63521
  }
@@ -63540,8 +63542,8 @@ var ACMCertificateProvider = class {
63540
63542
  }
63541
63543
  } catch (error) {
63542
63544
  const inUse = isCertificateInUseError(error);
63543
- orphanReason = inUse ? `old certificate ${physicalId} is still in use by another resource and was not deleted` : `old certificate ${physicalId} could not be deleted: ${String(error)}`;
63544
- this.logger.warn(`Failed to delete old ACM certificate ${physicalId} during replacement: ${String(error)}. ` + (inUse ? "This usually means a consumer (e.g. a CloudFront distribution) still references it; it can be deleted once DescribeCertificate.InUseBy is empty. " : "") + `The old certificate may be orphaned and require manual cleanup.`);
63545
+ orphanReason = inUse ? `old certificate ${physicalId} is still in use by another resource and was not deleted` : `old certificate ${physicalId} could not be deleted: ${safeStringify(error)}`;
63546
+ this.logger.warn(`Failed to delete old ACM certificate ${physicalId} during replacement: ${safeStringify(error)}. ` + (inUse ? "This usually means a consumer (e.g. a CloudFront distribution) still references it; it can be deleted once DescribeCertificate.InUseBy is empty. " : "") + `The old certificate may be orphaned and require manual cleanup.`);
63545
63547
  }
63546
63548
  const base = {
63547
63549
  physicalId: createResult.physicalId,
@@ -83152,6 +83154,7 @@ async function orphanCommand(pathArgs, options) {
83152
83154
  const { state, etag, migrationPending } = stateData;
83153
83155
  refuseMalformedState(state, stackInfo.stackName, targetRegion);
83154
83156
  refuseMalformedOutputs(state, stackInfo.stackName, targetRegion);
83157
+ refuseMalformedResourcePropertiesForOrphan(state, orphanLogicalIds, stackInfo.stackName, targetRegion);
83155
83158
  const missing = orphanLogicalIds.filter((id) => !(id in state.resources));
83156
83159
  if (missing.length > 0) {
83157
83160
  const have = Object.keys(state.resources ?? {}).join(", ");
@@ -94391,4 +94394,4 @@ function buildProgram() {
94391
94394
 
94392
94395
  //#endregion
94393
94396
  export { buildProgram };
94394
- //# sourceMappingURL=program-BLyj1ijG.js.map
94397
+ //# sourceMappingURL=program-BgbPkrcx.js.map