# VariantEntryPreset

```ts
type VariantEntryPreset = 
  | VariantPreset
  | "probe"
  | string & {
};
```

Defined in: packages/asset-client/src/index.ts:237

What `AssetVariant.preset` can actually hold.

⚠️ NOT `VariantPreset`, and the difference is a real bug the type used to
hide. Measured against the live API on 2026-08-21, one asset came back with
**29 variants, 25 of them `transform-<hash>`** — 86 % of the array — while the
type said every entry was one of eleven known presets. So this compiles:

```ts
for (const v of asset.variants ?? []) getAssetUrl(asset, v.preset);
```

`tsc` exits 0, and at runtime 25 of those 29 URLs come out as
`<sha>-undefined.undefined` and answer 404, because `PRESET_SHORT[preset]`
and `PRESET_EXT[preset]` are `undefined` for a hash that is not a preset.

The `transform-*` entries are NOT junk and are not being removed: they are
the materialised cache of past on-demand requests — still ready, still free
to fetch — and the inventory model treats them as a first-class
`transform-cache` family, which is exactly the question a composer asks
("what can I fetch cheaply right now?"). Deleting them would destroy that.

So the type tells the truth instead. `(string & {})` keeps autocomplete on
the known presets while admitting the rest, and a caller that wants to build
a URL now has to narrow first — which is the whole point.