Back to Blog
Tiago Duarte

OpenAI Just Deleted 18 Models. If Your Org Hard-Codes One, You Have a Countdown Timer.

OpenAI Just Deleted 18 Models. If Your Org Hard-Codes One, You Have a Countdown Timer.

OpenAI Just Deleted 18 Models. If Your Org Hard-Codes One, You Have a Countdown Timer.

What happened when OpenAI retired 18 model snapshots?

On July 23, 2026, OpenAI executed a scheduled shutdown of 18 model snapshots, including all five pre-5.3 Codex variants (gpt-5-codex through gpt-5.2-codex) plus chat-latest, deep-research, and computer-use-preview families. The shutdown was announced April 22. Any integration calling a retired snapshot by its exact ID started returning errors that day.

This was not a surprise to anyone reading the deprecations page, and that is the point. The date was public for three months. What broke on the 23rd was every place that pinned a snapshot ID as a string and never wired that string to anything that watches the deprecation calendar. The model did exactly what the vendor said it would do. The integration did not.

Why is a hard-coded model ID a time bomb in a Salesforce integration?

A hard-coded model ID couples your org to a version with a provider-controlled lifetime. When the provider retires that snapshot, every Apex callout or Flow referencing the string fails at once, in production, on the vendor's schedule instead of yours. It surfaces as a runtime error mid-transaction, not a deploy-time warning you can catch in a sandbox.

The string hides in more places than you expect. An Apex constant in one service class, copied into three others. A Flow HTTP callout body. A Named Credential path. The model dropdown on an Agentforce action. An MCP server config. In a large org with years of integration work, the same model ID is usually pasted across a dozen files, and no single search-and-replace finds all of them under deadline pressure. You learn where they all live at the worst possible time, which is when they are all throwing at once.

What does the stable-alias pattern look like in Salesforce?

Put a logical alias between your code and the provider's model. Store the mapping, logical name to current physical model ID, in a Custom Metadata Type, and have every callout resolve the physical ID at runtime. A forced cutover becomes a one-record metadata change you deploy, not a code hunt across classes hours after production started failing.

Create a Model_Alias__mdt Custom Metadata Type with a record per logical role. The DeveloperName is the alias (Reasoning_Default), and a Physical_Model__c field holds the current provider ID. Every callout asks the registry for the physical model instead of naming it:

// Model_Alias__mdt record: Reasoning_Default  ->  Physical_Model__c = 'gpt-5.3-codex'
public with sharing class ModelRegistry {
    public class ModelConfigException extends Exception {}

    public static String resolve(String logicalName) {
        Model_Alias__mdt cfg = Model_Alias__mdt.getInstance(logicalName);
        if (cfg == null || String.isBlank(cfg.Physical_Model__c)) {
            throw new ModelConfigException('No model mapped for alias: ' + logicalName);
        }
        return cfg.Physical_Model__c;
    }
}

Your callout builds its request with ModelRegistry.resolve('Reasoning_Default') and never sees a raw model string. When a snapshot dies, you edit one metadata record, deploy that record, and every class, Flow, and action pointed at that alias moves together. No Apex logic redeploys. No stragglers. The blast radius of a vendor deprecation drops from your entire integration surface to a single field value.

How do you survive a forced cutover without guessing which model to move to?

Keep an eval harness: a fixed set of representative prompts with expected-shape outputs you can run against a candidate model before switching. When a snapshot is retired, point the harness at the replacement, compare pass rate and latency, then shift the alias with a weighted canary instead of a hard flip you cannot undo cleanly.

The harness does not need to be elaborate. 15 to 30 real prompts pulled from actual usage, each with an assertion about the output you care about, valid JSON, a correct field extracted, a classification that matches. Run them against the new model, record the pass rate and P95 latency, and now the cutover is a decision backed by numbers instead of a hope that the replacement behaves like the thing it replaced. Route a small percentage of live traffic to the new alias value first, watch for a day, then move the rest. Rollback is reverting one metadata record, which is the same cheap operation as the cutover itself. That symmetry is the whole benefit: the change and the undo cost the same, so neither one is scary at 2pm on a production day.

When is this overkill?

If your agents run only on Agentforce-managed models, Salesforce owns the version lifecycle and you inherit an alias layer for free. The pattern earns its place when you call an external LLM directly from Apex, Flow, or an MCP server, where the model string is yours to maintain and the vendor's deprecation calendar is yours to track.

For a single nightly callout to one model, a well-named constant and a calendar reminder are enough, and building a registry for it is motion without value. The registry starts paying the moment that model ID is referenced in more than a couple of places, or across more than one org, or by anyone who is not the person who wrote the original callout. That is exactly the shape of most large orgs I work in, where the integration was written three consultants ago and the model string has quietly multiplied since. If that describes your org, the hour spent building the alias layer is cheaper than the afternoon you will otherwise spend grepping for a dead model ID while cases pile up.

OpenAI Just Deleted 18 Models. If Your Org Hard-Codes One, You Have a Countdown Timer. | ModernBlog