{"record":{"id":"ab0774f385aae036","repo":"anomalyco/sst","slug":"component-name-args-name-is-not-unique","errorCode":null,"errorMessage":"Component name ${args.name} is not unique.","messagePattern":"Component name (.+?) is not unique\\.","errorType":"validation","errorClass":"VisibleError","httpStatus":null,"severity":"error","filePath":"platform/src/components/link.ts","lineNumber":69,"sourceCode":"    // Ensure component names are unique\n    runtime.registerStackTransformation((args) => {\n      const isLinkable =\n        args.type.startsWith(\"sst:\") ||\n        Linkable.wrappedResources.has(args.type);\n      if (isLinkable && !args.opts.parent) {\n        const lcname = args.name.toLowerCase();\n\n        // \"App\" is reserved and cannot be used as a component name.\n        if (lcname === \"app\") {\n          throw new VisibleError(\n            `Component name \"${args.name}\" is reserved. Please choose a different name for your \"${args.type}\" component.`,\n          );\n        }\n\n        // Ensure linkable resources have unique names. This includes all SST components\n        // and non-SST components that are linkable.\n        if (links.has(lcname)) {\n          throw new VisibleError(`Component name ${args.name} is not unique.`);\n        }\n        links.add(lcname);\n      }\n      return {\n        opts: args.opts,\n        props: args.props,\n      };\n    });\n\n    // Create link refs\n    runtime.registerStackTransformation((args) => {\n      const resource = args.resource;\n      process.nextTick(() => {\n        if (Link.isLinkable(resource) && !args.opts.parent) {\n          try {\n            const link = resource.getSSTLink();\n            new Ref(args.name, args.type, link.properties, link.include);\n          } catch (e) {}","sourceCodeStart":51,"sourceCodeEnd":87,"githubUrl":"https://github.com/anomalyco/sst/blob/a0bd20f762883e72a35caccb4896c42ce5b3f707/platform/src/components/link.ts#L51-L87","documentation":"SST links resources to functions by their component name, so every top-level linkable component must have a unique name (case-insensitive). `Link.reset()` tracks names in a Set during stack registration and throws this VisibleError when a second top-level SST or linkable-wrapped component reuses a name already seen.","triggerScenarios":"Declaring two top-level components with the same name in any casing, e.g. `new sst.aws.Function(\"Api\", ...)` and `new sst.aws.Bucket(\"api\", ...)` in sst.config.ts; only applies to types starting with `sst:` or wrapped linkable resources with no parent.","commonSituations":"Copy-pasting a component block and forgetting to rename it; loops that generate components with a fixed name literal instead of an index; merging two stacks that each had a component with the same name; renaming a variable but not the component name string (Pulumi names must also change to avoid state conflicts).","solutions":["Rename one of the duplicate components to a unique name in sst.config.ts.","If components are generated in a loop, interpolate a unique suffix: `new sst.aws.Function(`Fn${i}`, ...)`.","Remember names are case-insensitive for this check (\"api\" vs \"Api\" still collide).","If this appeared after a rename, note Pulumi treats a new name as a new resource; you may need to delete the old resource or use `pulumi state rename` to keep state clean."],"exampleFix":"// before\nconst fn1 = new sst.aws.Function(\"Api\", { handler: \"src/a.handler\" });\nconst bucket = new sst.aws.Bucket(\"api\");\n// after\nconst fn1 = new sst.aws.Function(\"Api\", { handler: \"src/a.handler\" });\nconst bucket = new sst.aws.Bucket(\"Assets\", {});","handlingStrategy":"validation","validationCode":"const used = new Set<string>();\nfunction uniqueName(name: string) {\n  const key = name.toLowerCase();\n  if (used.has(key)) throw new Error(`Component name \"${name}\" is not unique.`);\n  used.add(key);\n  return name;\n}","typeGuard":"function isNameTaken(name: string, existing: Iterable<string>): boolean {\n  return new Set([...existing].map((n) => n.toLowerCase())).has(name.toLowerCase());\n}","tryCatchPattern":null,"preventionTips":["Use constants or a helper to generate component names so duplicates are caught early","In loops, always interpolate the index/key into the component name","Remember the uniqueness check is case-insensitive","After renames, reconcile Pulumi state to avoid stale resource names"],"tags":["sst","naming","duplicate","configuration"],"backgroundTag":"duplicate-resource-name","analyzedSha":"a0bd20f762883e72a35caccb4896c42ce5b3f707","analyzedAt":"2026-08-30T11:26:00.383Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}