@go-to-k/cdkd 0.201.0 → 0.202.0

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.
package/dist/cli.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { a as setAwsClients, i as resetAwsClients, r as getAwsClients, t as AwsClients } from "./aws-clients-DWUnLza1.js";
3
- import { $ as uploadCfnTemplate, A as S3StateBackend, At as PATTERN_B_NAME_PROPERTIES, B as Synthesizer, C as assertRegionMatch, Ct as normalizeAwsError, D as DagBuilder, E as DiffCalculator, Et as getLogger, F as buildDockerImage, Ft as withStackName, G as resolveSkipPrefix, H as getLegacyStateBucketName, I as formatDockerLoginError, J as warnDeprecatedNoPrefixCliFlag, K as resolveStateBucketWithDefault, L as getDockerCmd, M as AssetPublisher, Mt as generateResourceName, N as stringifyValue, Nt as generateResourceNameWithFallback, O as TemplateParser, Ot as runStackBuffered, P as WorkGraph, Pt as withSkipPrefix, Q as findLargeInlineResources, R as runDockerForeground, S as CloudControlProvider, T as applyRoleArnIfSet, U as resolveApp, V as getDefaultStateBucketName, W as resolveCaptureObservedState, X as CFN_TEMPLATE_URL_LIMIT, Y as CFN_TEMPLATE_BODY_LIMIT, Z as MIGRATE_TMP_PREFIX, _ as matchesCdkPath, _t as StackHasActiveImportsError, a as withRetry, b as ProviderRegistry, c as bold, ct as LocalMigrateError, d as green, dt as MissingCdkCliError, et as AssemblyReader, f as red, ft as NestedStackChildDirectDestroyError, g as CDK_PATH_TAG, gt as ResourceUpdateNotSupportedError, h as collectInlinePolicyNamesManagedBySiblings, ht as ResourceTimeoutError, i as withResourceDeadline, it as CdkdError, j as shouldRetainResource, jt as PATTERN_B_RESOURCE_TYPES, k as LockManager, kt as getLiveRenderer, l as cyan, lt as LocalStartServiceError, m as IAMRoleProvider, mt as ProvisioningError, n as DEFAULT_RESOURCE_WARN_AFTER_MS, nt as resolveBucketRegion, o as IMPLICIT_DELETE_DEPENDENCIES, p as yellow, pt as PartialFailureError, q as resolveStateBucketWithDefaultAndSource, r as DeployEngine, s as formatResourceLine, st as LocalInvokeBuildError$1, t as DEFAULT_RESOURCE_TIMEOUT_MS, u as gray, v as normalizeAwsTagsToCfn, vt as StackTerminationProtectionError, w as IntrinsicFunctionResolver, wt as withErrorHandling, x as findActionableSilentDrops, y as resolveExplicitPhysicalId, z as runDockerStreaming } from "./deploy-engine-5CVA5VWR.js";
3
+ import { $ as uploadCfnTemplate, A as S3StateBackend, At as PATTERN_B_NAME_PROPERTIES, B as Synthesizer, C as assertRegionMatch, Ct as normalizeAwsError, D as DagBuilder, E as DiffCalculator, Et as getLogger, F as buildDockerImage, Ft as withStackName, G as resolveSkipPrefix, H as getLegacyStateBucketName, I as formatDockerLoginError, J as warnDeprecatedNoPrefixCliFlag, K as resolveStateBucketWithDefault, L as getDockerCmd, M as AssetPublisher, Mt as generateResourceName, N as stringifyValue, Nt as generateResourceNameWithFallback, O as TemplateParser, Ot as runStackBuffered, P as WorkGraph, Pt as withSkipPrefix, Q as findLargeInlineResources, R as runDockerForeground, S as CloudControlProvider, T as applyRoleArnIfSet, U as resolveApp, V as getDefaultStateBucketName, W as resolveCaptureObservedState, X as CFN_TEMPLATE_URL_LIMIT, Y as CFN_TEMPLATE_BODY_LIMIT, Z as MIGRATE_TMP_PREFIX, _ as matchesCdkPath, _t as StackHasActiveImportsError, a as withRetry, b as ProviderRegistry, c as bold, ct as LocalMigrateError, d as green, dt as MissingCdkCliError, et as AssemblyReader, f as red, ft as NestedStackChildDirectDestroyError, g as CDK_PATH_TAG, gt as ResourceUpdateNotSupportedError, h as collectInlinePolicyNamesManagedBySiblings, ht as ResourceTimeoutError, i as withResourceDeadline, it as CdkdError, j as shouldRetainResource, jt as PATTERN_B_RESOURCE_TYPES, k as LockManager, kt as getLiveRenderer, l as cyan, lt as LocalStartServiceError, m as IAMRoleProvider, mt as ProvisioningError, n as DEFAULT_RESOURCE_WARN_AFTER_MS, nt as resolveBucketRegion, o as IMPLICIT_DELETE_DEPENDENCIES, p as yellow, pt as PartialFailureError, q as resolveStateBucketWithDefaultAndSource, r as DeployEngine, s as formatResourceLine, st as LocalInvokeBuildError$1, t as DEFAULT_RESOURCE_TIMEOUT_MS, u as gray, v as normalizeAwsTagsToCfn, vt as StackTerminationProtectionError, w as IntrinsicFunctionResolver, wt as withErrorHandling, x as findActionableSilentDrops, y as resolveExplicitPhysicalId, z as runDockerStreaming } from "./deploy-engine-CuJDHhTs.js";
4
4
  import { AsyncLocalStorage } from "node:async_hooks";
5
5
  import { randomBytes, randomUUID } from "node:crypto";
6
6
  import { CopyObjectCommand, CreateBucketCommand, DeleteBucketAnalyticsConfigurationCommand, DeleteBucketCommand, DeleteBucketCorsCommand, DeleteBucketIntelligentTieringConfigurationCommand, DeleteBucketInventoryConfigurationCommand, DeleteBucketLifecycleCommand, DeleteBucketMetricsConfigurationCommand, DeleteBucketPolicyCommand, DeleteBucketReplicationCommand, DeleteBucketTaggingCommand, DeleteBucketWebsiteCommand, DeleteObjectsCommand, GetBucketAccelerateConfigurationCommand, GetBucketCorsCommand, GetBucketEncryptionCommand, GetBucketLifecycleConfigurationCommand, GetBucketLocationCommand, GetBucketLoggingCommand, GetBucketNotificationConfigurationCommand, GetBucketPolicyCommand, GetBucketReplicationCommand, GetBucketTaggingCommand, GetBucketVersioningCommand, GetBucketWebsiteCommand, GetObjectCommand, GetObjectLockConfigurationCommand, GetPublicAccessBlockCommand, HeadBucketCommand, ListBucketAnalyticsConfigurationsCommand, ListBucketIntelligentTieringConfigurationsCommand, ListBucketInventoryConfigurationsCommand, ListBucketMetricsConfigurationsCommand, ListBucketsCommand, ListDirectoryBucketsCommand, ListObjectVersionsCommand, ListObjectsV2Command, NoSuchBucket, 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";
@@ -17236,7 +17236,7 @@ var CloudFrontDistributionProvider = class {
17236
17236
  const getResponse = await this.cloudFrontClient.send(new GetDistributionCommand({ Id: physicalId }));
17237
17237
  const domainName = getResponse.Distribution?.DomainName ?? "";
17238
17238
  const arn = getResponse.Distribution?.ARN;
17239
- await this.tryApplyTagDiff(arn, previousProperties["Tags"], properties["Tags"], physicalId);
17239
+ await this.applyTagDiff(arn, previousProperties["Tags"], properties["Tags"], physicalId, logicalId, resourceType);
17240
17240
  this.logger.debug(`Updated CloudFront Distribution ${physicalId}`);
17241
17241
  return {
17242
17242
  physicalId,
@@ -17489,32 +17489,44 @@ var CloudFrontDistributionProvider = class {
17489
17489
  };
17490
17490
  }
17491
17491
  /**
17492
- * Apply a tag diff to a distribution, best-effort.
17492
+ * Apply a tag diff to a distribution.
17493
17493
  *
17494
17494
  * CloudFront has no atomic overlay API for tags — `TagResource` adds /
17495
17495
  * overwrites and `UntagResource` removes. Run the removal first, then
17496
17496
  * the upsert, so a same-key value rewrite (which lands in `upserts`)
17497
17497
  * is not accidentally cleared by a stale Untag.
17498
17498
  *
17499
- * Errors are logged but not rethrown `update()` already succeeded
17500
- * the `UpdateDistribution` call before this is invoked, so propagating
17501
- * a tag-side error would flip a successful config update into a deploy
17502
- * failure that triggers an idempotent retry. A `warn` surfaces the
17503
- * unapplied delta to the operator without breaking the deploy.
17499
+ * Errors are RETHROWN as `ProvisioningError` (issue #740 fix) so the
17500
+ * deploy engine sees a failed update() and (a) does NOT write the new
17501
+ * properties.Tags into state the next deploy retries the tag-diff
17502
+ * against the still-old state, (b) surfaces the failure to the user
17503
+ * via the standard error path. The deploy engine's `withRetry` MAY
17504
+ * pick up some transient AWS errors via the cause-message-pattern
17505
+ * match (`retryable-errors.ts`'s `RETRYABLE_ERROR_MESSAGE_PATTERNS`),
17506
+ * but bare HTTP 429 throttles wrapped by update()'s outer catch reach
17507
+ * the classifier two levels deep and slip past its single-level
17508
+ * `.cause` walk — so the **load-bearing retry guarantee is the
17509
+ * next-deploy retry**, not in-deploy retry. This is acceptable: the
17510
+ * user sees the failure, can react, and the next `cdkd deploy`
17511
+ * re-fires the tag-diff against the still-old state cleanly.
17512
+ *
17513
+ * Trade-off: a tag-side failure flips an otherwise-successful
17514
+ * `UpdateDistribution` into a deploy failure, and the retry will
17515
+ * re-issue UpdateDistribution against the (now-current) config —
17516
+ * AWS accepts the no-op idempotently. The cost of that secondary
17517
+ * noise is much lower than the cost of silent tag drift the pre-#740
17518
+ * swallow caused.
17504
17519
  *
17505
17520
  * The ARN is unexpectedly absent only on a hypothetical SDK regression
17506
17521
  * (`GetDistribution` returns ARN as a required string in every SDK
17507
17522
  * shape verified so far). When that happens AND a tag delta exists,
17508
- * log a warn so the silent-drop this PR is closing does not silently
17509
- * resurface; when no delta exists, return without needing ARN.
17523
+ * THROW so the silent-drop does not silently resurface; when no delta
17524
+ * exists, return without needing ARN.
17510
17525
  */
17511
- async tryApplyTagDiff(arn, previousTags, newTags, physicalId) {
17526
+ async applyTagDiff(arn, previousTags, newTags, physicalId, logicalId, resourceType) {
17512
17527
  const { removed, upserts } = this.computeTagDiff(previousTags, newTags);
17513
17528
  if (removed.length === 0 && upserts.length === 0) return;
17514
- if (!arn) {
17515
- this.logger.warn(`CloudFront Distribution ${physicalId}: GetDistribution returned no ARN; skipping tag diff (removed=${removed.length}, upserts=${upserts.length}). Tags on AWS may drift from the template.`);
17516
- return;
17517
- }
17529
+ if (!arn) throw new ProvisioningError(`CloudFront Distribution ${physicalId}: GetDistribution returned no ARN; cannot apply tag diff (removed=${removed.length}, upserts=${upserts.length}). Refusing to silently drop the tag update — retry on next deploy or check SDK version.`, resourceType, logicalId, physicalId);
17518
17530
  try {
17519
17531
  if (removed.length > 0) {
17520
17532
  this.logger.debug(`Untagging CloudFront Distribution ${arn}: ${removed.join(", ")}`);
@@ -17531,7 +17543,8 @@ var CloudFrontDistributionProvider = class {
17531
17543
  }));
17532
17544
  }
17533
17545
  } catch (err) {
17534
- this.logger.warn(`CloudFront Distribution ${physicalId}: tag diff failed (removed=${removed.length}, upserts=${upserts.length}): ${err instanceof Error ? err.message : String(err)}. UpdateDistribution itself succeeded; tags on AWS may drift from the template until the next deploy.`);
17546
+ const cause = err instanceof Error ? err : void 0;
17547
+ throw new ProvisioningError(`CloudFront Distribution ${physicalId}: tag diff failed (removed=${removed.length}, upserts=${upserts.length}): ${err instanceof Error ? err.message : String(err)}. UpdateDistribution succeeded but TagResource/UntagResource did not — state has NOT been updated so the next deploy will retry the tag-diff.`, resourceType, logicalId, physicalId, cause);
17535
17548
  }
17536
17549
  }
17537
17550
  /**
@@ -31998,7 +32011,7 @@ var S3TablesProvider = class {
31998
32011
  providerRegion = process.env["AWS_REGION"];
31999
32012
  logger = getLogger().child("S3TablesProvider");
32000
32013
  handledProperties = new Map([
32001
- ["AWS::S3Tables::TableBucket", new Set(["TableBucketName"])],
32014
+ ["AWS::S3Tables::TableBucket", new Set(["TableBucketName", "Tags"])],
32002
32015
  ["AWS::S3Tables::Namespace", new Set(["TableBucketARN", "Namespace"])],
32003
32016
  ["AWS::S3Tables::Table", new Set([
32004
32017
  "TableBucketARN",
@@ -32023,7 +32036,8 @@ var S3TablesProvider = class {
32023
32036
  }
32024
32037
  }
32025
32038
  async update(logicalId, physicalId, resourceType, properties, previousProperties) {
32026
- if (resourceType === "AWS::S3Tables::Table") await this.applyTableTagsDiff(physicalId, previousProperties["Tags"], properties["Tags"]);
32039
+ if (resourceType === "AWS::S3Tables::Table") await this.applyTableTagsDiff(logicalId, physicalId, resourceType, previousProperties["Tags"], properties["Tags"]);
32040
+ else if (resourceType === "AWS::S3Tables::TableBucket") await this.applyTableBucketTagsDiff(logicalId, physicalId, resourceType, previousProperties["Tags"], properties["Tags"]);
32027
32041
  else this.logger.debug(`Update is no-op for ${resourceType} ${logicalId}`);
32028
32042
  return {
32029
32043
  physicalId,
@@ -32042,8 +32056,12 @@ var S3TablesProvider = class {
32042
32056
  this.logger.debug(`Creating S3 Table Bucket ${logicalId}`);
32043
32057
  const tableBucketName = properties["TableBucketName"];
32044
32058
  if (!tableBucketName) throw new ProvisioningError(`TableBucketName is required for S3 Table Bucket ${logicalId}`, resourceType, logicalId);
32059
+ const tags = this.cfnTagsToSdkMap(properties["Tags"]);
32045
32060
  try {
32046
- const tableBucketARN = (await this.getClient().send(new CreateTableBucketCommand({ name: tableBucketName }))).arn;
32061
+ const tableBucketARN = (await this.getClient().send(new CreateTableBucketCommand({
32062
+ name: tableBucketName,
32063
+ ...tags !== void 0 && { tags }
32064
+ }))).arn;
32047
32065
  this.logger.debug(`Successfully created S3 Table Bucket ${logicalId}: ${tableBucketARN}`);
32048
32066
  return {
32049
32067
  physicalId: tableBucketARN,
@@ -32235,6 +32253,7 @@ var S3TablesProvider = class {
32235
32253
  }
32236
32254
  const result = {};
32237
32255
  if (bucket.name !== void 0) result["TableBucketName"] = bucket.name;
32256
+ result["Tags"] = await this.readTagsBestEffort(physicalId);
32238
32257
  return result;
32239
32258
  }
32240
32259
  async readNamespaceCurrentState(physicalId) {
@@ -32502,40 +32521,88 @@ var S3TablesProvider = class {
32502
32521
  * value-only rewrite on key K isn't accidentally cleared by a stale
32503
32522
  * UntagResource pass (matches the CloudFront / S3Vectors pattern).
32504
32523
  *
32505
- * Tag ops are best-effort post-step in update(): a tag-side failure
32506
- * MUST NOT flip the deploy engine into a retry that would re-issue
32507
- * the no-op `update()` body. Log at warn instead so the user sees
32508
- * the unapplied delta but the deploy still progresses.
32509
- */
32510
- async applyTableTagsDiff(physicalId, previousTags, newTags) {
32524
+ * Tag-side failures THROW `ProvisioningError` (issue #740 fix): a
32525
+ * silent swallow would let the deploy engine write the new properties.Tags
32526
+ * to state as if applied, and the next deploy's diff (template Tags
32527
+ * vs new state Tags) sees no change → tag-diff never re-fires → AWS
32528
+ * tags stay stale forever. Throwing means: (a) state is NOT written,
32529
+ * (b) the next deploy retries the tag-diff against the still-old
32530
+ * state. The deploy engine's `withRetry` MAY pick up transient AWS
32531
+ * errors via the cause-message-pattern match in `retryable-errors.ts`,
32532
+ * but bare HTTP 429 throttles can slip past the classifier's
32533
+ * single-level `.cause` walk depending on wrapping — so the
32534
+ * **load-bearing retry guarantee is the next-deploy retry**, not
32535
+ * in-deploy retry. For the S3Tables Table case `update()` is
32536
+ * otherwise a no-op (the Table itself is immutable), so a tag-side
32537
+ * throw cleanly turns the whole update into a retry without
32538
+ * side-effects.
32539
+ *
32540
+ * The malformed-physicalId / GetTable-NotFound branches throw too
32541
+ * — both indicate a state-vs-AWS divergence the user needs to see,
32542
+ * not silently skip past.
32543
+ */
32544
+ async applyTableTagsDiff(logicalId, physicalId, resourceType, previousTags, newTags) {
32545
+ const prev = this.cfnTagsToSdkMap(previousTags) ?? {};
32546
+ const next = this.cfnTagsToSdkMap(newTags) ?? {};
32547
+ const removedKeys = Object.keys(prev).filter((k) => !(k in next));
32548
+ const upserts = {};
32549
+ for (const [k, v] of Object.entries(next)) if (prev[k] !== v) upserts[k] = v;
32550
+ if (removedKeys.length === 0 && Object.keys(upserts).length === 0) return;
32511
32551
  const parts = physicalId.split("|");
32512
- if (parts.length < 3) {
32513
- this.logger.warn(`applyTableTagsDiff: cannot derive table ARN from physicalId '${physicalId}' — skipping tag-diff`);
32514
- return;
32515
- }
32552
+ if (parts.length < 3) throw new ProvisioningError(`applyTableTagsDiff: cannot derive table ARN from physicalId '${physicalId}' (expected '<bucketArn>|<namespace>|<name>') — refusing to silently drop the tag update`, resourceType, logicalId, physicalId);
32516
32553
  const [tableBucketARN, namespace, name] = parts;
32517
- if (!tableBucketARN || !namespace || !name) {
32518
- this.logger.warn(`applyTableTagsDiff: cannot derive table ARN from malformed physicalId '${physicalId}' (empty part after split) — skipping tag-diff`);
32519
- return;
32554
+ if (!tableBucketARN || !namespace || !name) throw new ProvisioningError(`applyTableTagsDiff: cannot derive table ARN from malformed physicalId '${physicalId}' (empty part after split) — refusing to silently drop the tag update`, resourceType, logicalId, physicalId);
32555
+ const resourceArn = await this.lookupTableArn(tableBucketARN, namespace, name);
32556
+ if (!resourceArn) throw new ProvisioningError(`applyTableTagsDiff: GetTable returned no tableARN for ${physicalId} — table is gone or state is out-of-sync. Refusing to silently drop the tag update (run 'cdkd state orphan ${logicalId}' to clean up if the table was deleted out-of-band).`, resourceType, logicalId, physicalId);
32557
+ if (removedKeys.length > 0) try {
32558
+ await this.getClient().send(new UntagResourceCommand$15({
32559
+ resourceArn,
32560
+ tagKeys: removedKeys
32561
+ }));
32562
+ } catch (err) {
32563
+ const cause = err instanceof Error ? err : void 0;
32564
+ throw new ProvisioningError(`applyTableTagsDiff: UntagResource failed for ${resourceArn} (keys: ${removedKeys.join(", ")}): ${err instanceof Error ? err.message : String(err)}. State has NOT been updated so the next deploy will retry the tag-diff.`, resourceType, logicalId, physicalId, cause);
32565
+ }
32566
+ if (Object.keys(upserts).length > 0) try {
32567
+ await this.getClient().send(new TagResourceCommand$16({
32568
+ resourceArn,
32569
+ tags: upserts
32570
+ }));
32571
+ } catch (err) {
32572
+ const cause = err instanceof Error ? err : void 0;
32573
+ throw new ProvisioningError(`applyTableTagsDiff: TagResource failed for ${resourceArn} (keys: ${Object.keys(upserts).join(", ")}): ${err instanceof Error ? err.message : String(err)}. State has NOT been updated so the next deploy will retry the tag-diff.`, resourceType, logicalId, physicalId, cause);
32520
32574
  }
32575
+ }
32576
+ /**
32577
+ * Apply a tag-diff against a TableBucket resource ARN. Mirrors
32578
+ * `applyTableTagsDiff` for the Table case, but simpler: TableBucket's
32579
+ * `physicalId` IS the bucket ARN, so no `GetTableBucket` lookup hop
32580
+ * is needed (the Table version needs `GetTable` to recover the real
32581
+ * ARN from the cdkd-compound `<bucketArn>|<namespace>|<name>` physical id).
32582
+ *
32583
+ * Same throw semantics as `applyTableTagsDiff` (per issue #740 / PR
32584
+ * #741): tag-side failures THROW `ProvisioningError` so state is NOT
32585
+ * written, and the next deploy retries against the still-old state.
32586
+ * `update()` for AWS::S3Tables::TableBucket is otherwise a no-op (the
32587
+ * bucket itself is immutable), so a tag-side throw cleanly turns the
32588
+ * whole update into a clean retry with no side-effects.
32589
+ */
32590
+ async applyTableBucketTagsDiff(logicalId, physicalId, resourceType, previousTags, newTags) {
32521
32591
  const prev = this.cfnTagsToSdkMap(previousTags) ?? {};
32522
32592
  const next = this.cfnTagsToSdkMap(newTags) ?? {};
32523
32593
  const removedKeys = Object.keys(prev).filter((k) => !(k in next));
32524
32594
  const upserts = {};
32525
32595
  for (const [k, v] of Object.entries(next)) if (prev[k] !== v) upserts[k] = v;
32526
32596
  if (removedKeys.length === 0 && Object.keys(upserts).length === 0) return;
32527
- const resourceArn = await this.lookupTableArn(tableBucketARN, namespace, name);
32528
- if (!resourceArn) {
32529
- this.logger.warn(`applyTableTagsDiff: GetTable returned no tableARN for ${physicalId} — skipping tag-diff (table gone? state out-of-sync?)`);
32530
- return;
32531
- }
32597
+ const resourceArn = physicalId;
32532
32598
  if (removedKeys.length > 0) try {
32533
32599
  await this.getClient().send(new UntagResourceCommand$15({
32534
32600
  resourceArn,
32535
32601
  tagKeys: removedKeys
32536
32602
  }));
32537
32603
  } catch (err) {
32538
- this.logger.warn(`applyTableTagsDiff: UntagResource failed for ${resourceArn} (keys: ${removedKeys.join(", ")}): ${err instanceof Error ? err.message : String(err)}`);
32604
+ const cause = err instanceof Error ? err : void 0;
32605
+ throw new ProvisioningError(`applyTableBucketTagsDiff: UntagResource failed for ${resourceArn} (keys: ${removedKeys.join(", ")}): ${err instanceof Error ? err.message : String(err)}. State has NOT been updated so the next deploy will retry the tag-diff.`, resourceType, logicalId, physicalId, cause);
32539
32606
  }
32540
32607
  if (Object.keys(upserts).length > 0) try {
32541
32608
  await this.getClient().send(new TagResourceCommand$16({
@@ -32543,7 +32610,8 @@ var S3TablesProvider = class {
32543
32610
  tags: upserts
32544
32611
  }));
32545
32612
  } catch (err) {
32546
- this.logger.warn(`applyTableTagsDiff: TagResource failed for ${resourceArn} (keys: ${Object.keys(upserts).join(", ")}): ${err instanceof Error ? err.message : String(err)}`);
32613
+ const cause = err instanceof Error ? err : void 0;
32614
+ throw new ProvisioningError(`applyTableBucketTagsDiff: TagResource failed for ${resourceArn} (keys: ${Object.keys(upserts).join(", ")}): ${err instanceof Error ? err.message : String(err)}. State has NOT been updated so the next deploy will retry the tag-diff.`, resourceType, logicalId, physicalId, cause);
32547
32615
  }
32548
32616
  }
32549
32617
  };
@@ -51856,7 +51924,7 @@ function reorderArgs(argv) {
51856
51924
  */
51857
51925
  async function main() {
51858
51926
  const program = new Command();
51859
- program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.201.0");
51927
+ program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.202.0");
51860
51928
  program.addCommand(createBootstrapCommand());
51861
51929
  program.addCommand(createSynthCommand());
51862
51930
  program.addCommand(createListCommand());