anomalyco/sst · error · VisibleError
Component name "${args.name}" is reserved. Please choose a d
Error message
Component name "${args.name}" is reserved. Please choose a different name for your "${args.type}" component. What it means
SST reserves the component name "app" (case-insensitive) for top-level SST components, because the name is used internally (e.g. for app/linking infrastructure) and would collide. During stack registration, `Link.reset()` installs a stack transformation that rejects any top-level linkable SST component whose lowercase name equals "app" by throwing a VisibleError.
Source
Thrown at platform/src/components/link.ts:61
...properties,
},
});
}
}
export function reset() {
const links = new Set<string>();
// Ensure component names are unique
runtime.registerStackTransformation((args) => {
const isLinkable =
args.type.startsWith("sst:") ||
Linkable.wrappedResources.has(args.type);
if (isLinkable && !args.opts.parent) {
const lcname = args.name.toLowerCase();
// "App" is reserved and cannot be used as a component name.
if (lcname === "app") {
throw new VisibleError(
`Component name "${args.name}" is reserved. Please choose a different name for your "${args.type}" component.`,
);
}
// Ensure linkable resources have unique names. This includes all SST components
// and non-SST components that are linkable.
if (links.has(lcname)) {
throw new VisibleError(`Component name ${args.name} is not unique.`);
}
links.add(lcname);
}
return {
opts: args.opts,
props: args.props,
};
});
// Create link refsView on GitHub (pinned to a0bd20f762)
Solutions
- Rename the component to something other than "App"/"app" in sst.config.ts, e.g. "MyApp" or "Api".
- Check casing: the check is case-insensitive, so "APP", "app", and "App" all fail.
- If the component is not intentionally top-level, give it a parent so the transformation skips it.
- Run `sst deploy`/`sst dev` again after renaming; also update references to the component's resource name in links or Resource lookups.
Example fix
// before
const app = new sst.aws.Function("App", {
handler: "src/api.handler",
});
// after
const app = new sst.aws.Function("Api", {
handler: "src/api.handler",
}); Defensive patterns
Strategy: validation
Validate before calling
// In sst.config.ts, before creating a top-level component
function assertValidComponentName(name: string) {
if (name.toLowerCase() === "app")
throw new Error(`Component name "${name}" is reserved; use a different name.`);
return name;
}
const name = assertValidComponentName("Api"); Type guard
function isReservedName(name: string): boolean {
return name.toLowerCase() === "app";
} Prevention
- Never name top-level SST components "App"/"app" in any casing
- Use descriptive resource names ("Api", "Web", "Db") instead of the generic "App"
- Keep sub-components nested under a parent so name-collision rules don't apply
- Add a code-review checklist item for component naming conventions
When it happens
Trigger: Declaring any top-level SST component (one without a parent) named "App" or "app" in any casing, e.g. `new sst.aws.Function("App", {...})` or a wrapped linkable resource named "app" in sst.config.ts. Only fires when the resource type starts with `sst:` or is in Linkable.wrappedResources and has no parent.
Common situations: Copying example code that names the primary function/app component "App"; renaming a component to match a variable called `app`; typos where the developer intended `new sst.App(...)`-style naming; refactors where a subcomponent lost its parent and became top-level.
Related errors
- Component name ${args.name} is not unique.
- Invalid function definition for the "${name}" Function
- Cannot access `nodes.loadBalancer` when no public ports are
- You must provide the ports to expose via "loadBalancer.rules
- You must provide a container name in "loadBalancer.rules" wh
AI-assisted analysis of anomalyco/sst@a0bd20f762 (2026-08-30).
Data as JSON: /api/errors/de4c29bf11a6d092.
Report an issue: GitHub.