anomalyco/sst · error · VisibleError

At least one of function, queue, or topic is required for th

Error message

At least one of function, queue, or topic is required for the "${n.name}" bucket notification.

What it means

Each entry in a bucket's `notifications` array must designate exactly one subscription target. When a notification has none of `function`, `queue`, or `topic` set, SST cannot know where to send the event and throws this VisibleError during normalization.

Source

Thrown at platform/src/components/aws/bucket-notification.ts:63

  constructor(name: string, args: Args, opts?: ComponentResourceOptions) {
    super(__pulumiType, name, args, opts);

    const self = this;
    const bucket = output(args.bucket);
    const notifications = normalizeNotifications();
    const { config, functionBuilders } = createNotificationsConfig();
    const notification = createNotification();

    this.functionBuilders = functionBuilders;
    this.notification = notification;

    function normalizeNotifications() {
      return output(args.notifications).apply((notifications) =>
        notifications.map((n) => {
          const count =
            (n.function ? 1 : 0) + (n.queue ? 1 : 0) + (n.topic ? 1 : 0);
          if (count === 0)
            throw new VisibleError(
              `At least one of function, queue, or topic is required for the "${n.name}" bucket notification.`,
            );
          if (count > 1)
            throw new VisibleError(
              `Only one of function, queue, or topic is allowed for the "${n.name}" bucket notification.`,
            );

          return {
            ...n,
            events: n.events ?? [
              "s3:ObjectCreated:*",
              "s3:ObjectRemoved:*",
              "s3:ObjectRestore:*",
              "s3:ReducedRedundancyLostObject",
              "s3:Replication:*",
              "s3:LifecycleExpiration:*",
              "s3:LifecycleTransition",
              "s3:IntelligentTiering",

View on GitHub (pinned to a0bd20f762)

Solutions

  1. Add a `function`, `queue`, or `topic` property to the notification entry
  2. If the target is optional in your config, filter out empty notification entries before passing them to SST
  3. Check that the target resource reference isn't undefined due to a typo

Example fix

// before
notifications: [{ name: "onUpload", events: ["s3:ObjectCreated:*"] }]
// after
notifications: [{
  name: "onUpload",
  events: ["s3:ObjectCreated:*"],
  function: "src/notification.handler",
}]
Defensive patterns

Strategy: validation

Validate before calling

const notifications = rawNotifications.filter(n => n.function || n.queue || n.topic);
new sst.aws.Bucket("Bucket", { notifications });

Type guard

function hasNotificationTarget(n: { function?: unknown; queue?: unknown; topic?: unknown }): boolean {
  return Boolean(n.function || n.queue || n.topic);
}

Try / catch

try {
  new sst.aws.Bucket("B", { notifications: raw });
} catch (e) {
  if ((e as Error).message.includes("At least one of function, queue, or topic is required")) {
    console.error("Notification entry is missing its target");
  }
  throw e;
}

Prevention

When it happens

Trigger: Passing a `notifications: [{ name: "x", events: [...] }]` entry to `bucket.notifications` (or constructor args) with no `function`, `queue`, or `topic` property.

Common situations: Copy-pasted notification config with target removed; conditionally built target object that ends up undefined; refactoring from one target type to another and deleting the old key first.

Understand the failure class

Background: "X is required", "must be set", "cannot be empty": the missing-required-config error family, from Vertex AI project/location to WeChat keys — this error's family across 18 libraries.

Related errors


AI-assisted analysis of anomalyco/sst@a0bd20f762 (2026-08-30). Data as JSON: /api/errors/9a974b65c6482271. Report an issue: GitHub.