1---
2title: Adopting Resources
3description: How alchemy takes ownership of pre-existing cloud resources — recovery by default, --adopt for foreign resources, and the programmatic AdoptPolicy.
4---
5
6Two situations put alchemy in front of a cloud resource it has no state for: existing infrastructure you want alchemy to start managing, and a fresh (or wiped) state store sitting in front of resources alchemy already created.
7
8```sh
9bun alchemy deploy --adopt
10```
11
12## How the engine decides
13
14When a resource has no prior state, the engine calls the provider's
15`read` to check whether the resource already exists in the cloud. The
16return value drives one of three paths:
17
18| `read` returns | Without `--adopt` | With `--adopt` |
19| ------------------- | ------------------------- | --------------------- |
20| `undefined` | create | create |
21| owned (plain attrs) | silent adopt | silent adopt |
22| `Unowned(attrs)` | fail `OwnedBySomeoneElse` | take over (silently) |
23
24"Owned" means the provider can prove the resource was created by *this* stack/stage/logical-id — typically by inspecting tags or a naming convention.
25
26The same table drives the provider-side contract: see [Adoption in Resource Lifecycle](/infrastructure-as-code/resource-lifecycle#adoption) for the engine's routing and [the `read` operation](/infrastructure-as-code/provider#read) for how a provider returns `Unowned(attrs)`.
27
28## Recovery is the default
29
30Re-importing owned resources into a fresh state store needs **no** flag — recovering a wiped state store for resources you already own is the default behavior.
31
32`--adopt` only matters when the provider reports a resource exists but isn't ours. That's the deliberately load-bearing case: by default alchemy refuses to silently overwrite tags/config of a resource it can't prove ownership of. `--adopt` says "yes, take it over."
33
34```sh
35# Re-import existing alchemy-tagged resources into a fresh state
36# store — no flag needed for these. Ones with foreign ownership tags
37# will surface as `OwnedBySomeoneElse` errors.
38alchemy deploy
39
40# Preview the takeover without applying it.
41alchemy plan --adopt
42
43# Force takeover of any conflicting resource regardless of tags.
44alchemy deploy --adopt
45```
46
47## The `--adopt` flag
48
49`--adopt` opts the *entire* deploy in to adoption-on-conflict — it is provided as a single `AdoptPolicy` layer over the whole stack execution, not per resource.
50
51The default is `false` so an unintentional collision still surfaces loudly instead of silently overwriting someone else's resource. The option is part of the shared `ExecStackOptions` that every stack-executing command (including `dev`) runs through.
52
53## When adoption is refused: `OwnedBySomeoneElse`
54
55When `read` reports an existing resource as `Unowned` and adoption is off, the deploy fails with the typed `OwnedBySomeoneElse` error, carrying `message`, `resourceType`, `logicalId`, and `physicalName`.
56
57You have three ways out: re-tag the cloud resource so the provider recognizes it as yours, pick a different physical name so there is no collision, or re-run with `--adopt` (or `adopt(true)`) to force a takeover.
58
59## Programmatic adoption
60
61You can also enable adoption programmatically by piping the `adopt` combinator onto a deploy effect from `alchemy/AdoptPolicy`:
62
63```typescript
64import { adopt } from "alchemy/AdoptPolicy";
65
66yield* deploy(
67 Effect.gen(function* () {
68 yield* Cloudflare.Worker("API", { /* ... */ });
69 }),
70).pipe(adopt(true));
71```
72
73`AdoptPolicy` is consulted at plan time, so the combinator must wrap the *deploy* (or test runner's `stack.deploy(...)`) — not the inner resource-declaration effect.
74
75`adopt()` with no argument means `true`, and it also accepts an `Effect<boolean>` for dynamic policies:
76
77```typescript
78deployEffect.pipe(adopt()); // same as adopt(true)
79deployEffect.pipe(adopt(decidePolicy)); // Effect<boolean>, resolved at plan time
80```
81
82## Resources without ownership semantics
83
84Providers with no tag concept (e.g. APIs that always return a singleton by name) always return plain attrs from `read`, so they silently adopt unconditionally — `--adopt` is a no-op for them.
85
86For the full lost-state-store recovery walkthrough (state explorer → state delete → deploy), see [Inspecting State](/cli/inspecting-state).
87
88## Where next
89
90- [deploy](/cli/deploy) — the command that carries `--adopt`
91- [Inspecting State](/cli/inspecting-state) — recover a lost or wiped state store
92- [Resource Lifecycle](/infrastructure-as-code/resource-lifecycle) — where adoption sits in the engine
93- [Providers](/infrastructure-as-code/provider) — implementing `read` and `Unowned`