anomalyco/sst · error · VisibleError

Do not set both "public" and "publicIp" for the "${name}" Ta

Error message

Do not set both "public" and "publicIp" for the "${name}" Task. "publicIp" has been deprecated, use "public" instead.

What it means

SST's Task component (ECS) renamed the `publicIp` argument to `public`. Because the two overlap in meaning, the constructor in platform/src/components/aws/task.ts:310 refuses to proceed when both are supplied, since it cannot tell which intent is authoritative. `publicIp` is deprecated and kept only for backwards compatibility.

Source

Thrown at platform/src/components/aws/task.ts:310

  private readonly containerNames: Output<Output<string>[]>;
  private readonly dev: boolean;

  constructor(
    name: string,
    args: TaskArgs,
    opts: ComponentResourceOptions = {},
  ) {
    super(__pulumiType, name, args, opts);

    const self = this;
    const dev = normalizeDev();
    const architecture = normalizeArchitecture(args);
    const cpu = normalizeCpu(args);
    const memory = normalizeMemory(cpu, args);
    const storage = normalizeStorage(args);
    const containers = normalizeContainers("task", args, name, architecture);
    if (args.public !== undefined && args.publicIp !== undefined)
      throw new VisibleError(
        `Do not set both "public" and "publicIp" for the "${name}" Task. "publicIp" has been deprecated, use "public" instead.`,
      );
    const isPublic = args.public ?? false;
    const vpc = normalizeVpc();
    const hasPublicIp = isPublic || (args.publicIp ?? vpc.isSstVpc);
    const publicSecurityGroup = createPublicSecurityGroup();

    const taskRole = createTaskRole(
      name,
      args,
      opts,
      self,
      dev,
      dev
        ? [
            {
              actions: ["appsync:*"],
              resources: ["*"],

View on GitHub (pinned to a0bd20f762)

Solutions

  1. Remove the deprecated `publicIp` property from the Task args and keep only `public`.
  2. If you intentionally relied on `publicIp: false` while defaulting `public` elsewhere, set `public` explicitly to the desired value instead.
  3. Run `sst upgrade` and check the Task docs to confirm all other renamed args were migrated too.

Example fix

// before
new sst.aws.Task("Api", {
  public: true,
  publicIp: true,
  // ...
});
// after
new sst.aws.Task("Api", {
  public: true,
  // ...
});
Defensive patterns

Strategy: validation

Validate before calling

const taskArgs = { name: "Api", public: true, publicIp: true };
if (taskArgs.public !== undefined && taskArgs.publicIp !== undefined) {
  throw new Error("Task defines both 'public' and deprecated 'publicIp'; remove 'publicIp'.");
}
new sst.aws.Task("Api", taskArgs);

Type guard

function usesDeprecatedPublicIp(args: sst.aws.TaskArgs): boolean {
  return (args as { publicIp?: boolean }).publicIp !== undefined;
}

Prevention

When it happens

Trigger: Constructing a new Task (or sst.aws.Task) with both `public` and `publicIp` defined in the args object, e.g. `new sst.aws.Task("MyTask", { public: true, publicIp: true, ... })`.

Common situations: Migrating an old sst.config.ts written against a previous SST version where `publicIp` was the valid flag, then adding the new `public` field without removing `publicIp`; or copy-pasting config from docs of mixed versions; or an AI/codemod adding `public` on top of existing `publicIp`.

Related errors


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