Skip to content

fix: don't blank out generated types on sst remove - #7045

Open
AliAladraj wants to merge 1 commit into
anomalyco:devfrom
AliAladraj:fix/remove-keeps-types
Open

AliAladraj wants to merge 1 commit into
anomalyco:devfrom
AliAladraj:fix/remove-keeps-types

Conversation

@AliAladraj

Copy link
Copy Markdown

Fixes #6907

Root cause

sst remove does not delete the generated type files — it regenerates them empty.

pkg/project/run.go:633 calls types.Generate(...) unconditionally after every stack command, remove included. After a successful remove, complete.Links is empty, so:

  • typescript.Generate rewrites sst-env.d.ts in every package.json directory with an empty Resource interface (pkg/types/typescript/typescript.go:92-104)
  • python.Generate truncates sst.pyi the same way

The result is that removing one stage breaks typechecking in the editor and in CI for anyone still working against another stage.

This looks incidental rather than deliberate — every neighbouring post-run step in the same function guards on input.Command (lines 636, 646, 652, 668, 673), and there is no comment or commit message justifying running generation on remove.

Fix

Skip type generation for the remove command, matching the surrounding convention.

dev and deploy still regenerate types, so there is no staleness regression. A removed stage simply leaves the last generated types on disk, which is what the issue asks for.

Verification

  • go build ./cmd/sst — succeeds.
  • go vet ./pkg/project/ — clean.
  • gofmt — clean.
  • go test ./pkg/project/... ./pkg/types/... — all pass except TestEnvForIncludesWranglerPath, which fails identically on an unmodified dev checkout (env_test.go:53: unexpected end of JSON input) and is unrelated to this change.

Related

#6418 reports directory not empty, rmdir '<path>/.sst/types'. I looked for it while in this code and could not reproduce or locate it: there is no .sst/types path anywhere in the current source (pkg/project/path/path.go defines only .sst, .sst/platform, .sst/log, .sst/provider-lock.json), and the message is formatted the way Node reports ENOTEMPTY, not the way Go does. It most likely originates from SST v2 or from user tooling, so I have not touched it here.

After a successful `sst remove` the stage no longer has any links, so the
unconditional `types.Generate` call at the end of the run rewrote every
`sst-env.d.ts` (and `sst.pyi`) with an empty `Resource` interface. The files
were not deleted, but they were emptied, which breaks typechecking in an
editor or CI for anyone who removes one stage while still working against
another.

Skip type generation for the `remove` command, matching the neighbouring
post-run steps that already guard on `input.Command`. `dev` and `deploy`
still regenerate types, so there is no staleness regression.
@AlperSakarya

AlperSakarya commented Oct 31, 2026 •

Copy link
Copy Markdown

@AliAladraj, thanks for the fix. Your commits are carried, with your authorship, in the community fork, as sst-community/sst#201 (tracked in sst-community/sst#199), and released in v4.23.1: https://github.com/sst-community/sst/releases/tag/v4.23.1

One change on top of yours: the type files are skipped only when the remove leaves no links in the stage, and regenerated from what remains otherwise. That keeps --target removes and removes that fail partway working. I tested it on AWS with two buckets: removing one bucket by --target rewrote the types with the other, and removing the last one left the types untouched.

To try it: npm install sst@npm:@sst-community/sst.

The community fork accepts pull requests and issues, so you are welcome to send them there as well.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

The sst remove command shouldn't delete all generated types

2 participants