> ## Documentation Index
> Fetch the complete documentation index at: https://manifest.build/llm-gateway/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Autofix

> Use Manifest Autofix through the LLM Gateway to repair a malformed request and retry it once before fallback.

<div className="deploy-mode-toggle" role="group" aria-label="Deployment mode">
  <button type="button" data-deploy-mode="cloud">Cloud</button>
  <button type="button" data-deploy-mode="selfhosted">Self-hosted</button>
</div>

Some requests fail because of the request, not the model. A parameter the provider doesn't accept, a tool schema in the wrong shape, a model name that moved. Switching to a fallback model doesn't help, because the next model rejects the same body.

Autofix handles that case. When a request fails with a repairable error, the gateway sends the failed request and the provider's error to a healing service, gets a corrected request back, and sends it once more. It runs **before** the fallback chain, so fallback is still the safety net if the repair doesn't land.

## When it runs

Autofix only touches request-side 4xx errors, where the provider is telling you the request was wrong:

| Status | Meaning                                         |
| ------ | ----------------------------------------------- |
| `400`  | Bad request, usually a malformed parameter      |
| `404`  | Not found, usually a model name that moved      |
| `422`  | Unprocessable, usually a schema the API rejects |

It deliberately skips `401`, `403`, `429`, and every `5xx`. A bad key, a rate limit, or a provider outage isn't something a rewritten body can fix, so those go straight to [fallback](/llm-gateway/docs/llm-gateway/docs/llm-gateway#fallback).

Renamed models are covered through the provider itself. When a request names a model the gateway hasn't catalogued but the provider and credentials are unambiguous, the gateway forwards it anyway. The provider answers with its real error, typically a `404` for a model that no longer exists, and that error goes through the normal Autofix path. A patch that corrects the model name serves the request.

## How it works

<Steps>
  <Step title="The request fails">
    A provider returns a repairable 4xx. The gateway normalizes the error into a
    message, type, and parameter.
  </Step>

  <Step title="The gateway asks for a patch">
    The failed request and the normalized error go to the hosted healing
    service, which returns a corrected request body.
  </Step>

  <Step title="One retry">
    The gateway sends the patched request. There is no retry budget: it tries
    exactly once.
  </Step>

  <Step title="Fallback if it still fails">
    If the patched request fails too, the gateway reports the outcome and hands
    off to your fallback chain as normal.
  </Step>
</Steps>

Autofix covers non-streaming responses, and streaming responses that fail before the first byte reaches your client. Once bytes are on the wire there's nothing to rewrite.

## Turning it on

Autofix is a per-harness toggle, and you meet it at two moments.

<div data-deploy="selfhosted">
  Nothing to deploy or configure: your install talks to the hosted Manifest Autofix service directly.
</div>

### When you create a harness

The Connect Harness modal shows an Autofix toggle under the name field, pre-set to on. You decide there, and the choice is stored on the harness. This works the same on Cloud and self-hosted.

<Frame caption="The Autofix toggle in the Connect Harness modal, pre-set to on.">
  <img src="https://mintcdn.com/manifest-879ce4a3/byfl07OAIZQ7T8qO/llm-gateway/docs/images/autofix-connect-harness.png?fit=max&auto=format&n=byfl07OAIZQ7T8qO&q=85&s=f732a0180cc4f63bf63ddce41744e943" alt="The Connect Harness modal with the Autofix toggle switched on under the name field" width="1080" height="1088" data-path="llm-gateway/docs/images/autofix-connect-harness.png" />
</Frame>

### Harnesses you already have

A harness that existed before Autofix keeps its state: the gateway never flips the toggle for you.

<div data-deploy="cloud">
  On LLM Gateway Cloud, those harnesses are already on. You can switch any of them off on its **Settings** page.
</div>

<div data-deploy="selfhosted">
  Enable each one from its **Settings** page or from the sidebar card.
</div>

The dashboard shows a sidebar card while any harness has Autofix off. It opens a modal listing those harnesses with individual toggles, and you can dismiss it for the browser session.

<Frame caption="The Autofix toggle on a harness's Settings page.">
  <img src="https://mintcdn.com/manifest-879ce4a3/byfl07OAIZQ7T8qO/llm-gateway/docs/images/autofix-settings-toggle.png?fit=max&auto=format&n=byfl07OAIZQ7T8qO&q=85&s=fa66dc67f7f7edbb2da2c71eb860c804" alt="A harness's Settings page with the Autofix failing requests toggle switched on" width="1392" height="428" data-path="llm-gateway/docs/images/autofix-settings-toggle.png" />
</Frame>

<Frame caption="The modal opened by the sidebar card, one toggle per harness.">
  <img src="https://mintcdn.com/manifest-879ce4a3/byfl07OAIZQ7T8qO/llm-gateway/docs/images/autofix-enable-modal.png?fit=max&auto=format&n=byfl07OAIZQ7T8qO&q=85&s=7455aa4e05f1a6cebff7290f8e3c7b6a" alt="The Enable Autofix modal listing harnesses that have Autofix off, each with its own toggle" width="1120" height="740" data-path="llm-gateway/docs/images/autofix-enable-modal.png" />
</Frame>

## Your data

<div data-deploy="cloud">
  Here is exactly what Autofix sends to the healing service, and when nothing is sent.
</div>

<div data-deploy="selfhosted">
  Self-hosting is often a privacy choice, so here is exactly what leaves your machine, and when nothing does.

  The first time you enable Autofix, your install records a one-time consent: enabling it means you agree that failing requests are sent to the hosted healing service, as set out in the [terms](https://manifest.build/terms/). Any enable path records it. Your install identifies itself with an anonymous install id, the same id [telemetry](/llm-gateway/docs/llm-gateway/docs/reference/telemetry) uses.
</div>

When Autofix repairs a request, the gateway sends the failed request, including its message content, plus the provider's error response to the healing service.

Provider API keys and OAuth tokens are never sent: credentials travel in request headers, which are not part of the payload sent to the healing service. The provider's error response is scrubbed for secrets before it is sent.

Nothing is sent for requests that succeed. No request data is ever sent while the toggle is off; the only call that can still happen is the boot health check, which carries no request content.

<div data-deploy="selfhosted">
  Self-hosted deployments can also switch Autofix off globally, which stops every call to the healing service, including the health check at boot. See [Environment variables](#environment-variables).
</div>

See the [privacy policy](https://manifest.build/privacy/) and the [terms](https://manifest.build/terms/).

## Guardrails

Autofix is built to stay out of the way when it isn't working:

* **One attempt.** A patched request is sent once. It never loops.
* **Failures degrade quietly.** If the healing service errors or times out, your agent gets the original provider error. Autofix never turns a provider's 400 into a gateway 500.
* **A slow healer stops being asked.** After three consecutive transport failures, the gateway stops calling it for 30 seconds so a down service doesn't add latency to every failing request. One successful call clears the streak.
* **Startup never waits.** In production, the gateway pings the healing service once at boot, fire-and-forget, and logs a warning if it's unreachable. It never blocks startup, and it's skipped entirely when Autofix is disabled globally.
* **Fallback still runs.** Autofix sits in front of the chain, it doesn't replace it.

## Seeing what it did

Open any request in the dashboard's request log. Requests that went through Autofix carry a panel showing what changed and whether the retry succeeded. Only a successful patched retry counts as recovered by Autofix.

<Frame caption="A repaired request: the failed attempt, the provider's error, and the Autofix panel showing the patch.">
  <img src="https://mintcdn.com/manifest-879ce4a3/byfl07OAIZQ7T8qO/llm-gateway/docs/images/autofix-request-panel.png?fit=max&auto=format&n=byfl07OAIZQ7T8qO&q=85&s=93fd6449738fecf5b634557de1046007" alt="The request drawer on a repaired request, with the failed and patched attempts listed and the Autofix panel showing what changed" width="2000" height="1135" data-path="llm-gateway/docs/images/autofix-request-panel.png" />
</Frame>

The failed original and its patched retry are separate [provider attempts](/llm-gateway/docs/llm-gateway/docs/observability#requests-and-provider-attempts), so with [request logs](/llm-gateway/docs/llm-gateway/docs/request-logs) on you can read both bodies side by side and see exactly which field was rewritten.

The **Overview** page aggregates the same data across a time range:

| Card                     | What it measures                                                         |
| ------------------------ | ------------------------------------------------------------------------ |
| **Success rate**         | Share of requests that ended successfully, however many attempts it took |
| **Recovered requests**   | Share of requests that failed at least one attempt and still succeeded   |
| **Recovered by Autofix** | Count of requests where a patched retry is what saved it                 |

Both **Recovered** cards link through to the matching filter on the request log.

<div data-deploy="selfhosted">
  ## Environment variables

  <Note>
    Self-hosted only. On [LLM Gateway Cloud](https://app.manifest.build) there is no
    server to configure: everything Autofix related lives in the dashboard.
  </Note>

  Autofix needs no setup. Every variable below is optional and adjusts behavior:

  | Variable                      | Default       | Description                                                                                                                                                                                                                                         |
  | ----------------------------- | ------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
  | `AUTOFIX_GLOBAL_ENABLED`      | `true`        | Set `false` to turn Autofix off for the whole deployment. No call reaches the healing service, including the boot health check                                                                                                                      |
  | `AUTOFIX_TIMEOUT_MS`          | `10000`       | Timeout per healing call, in milliseconds                                                                                                                                                                                                           |
  | `AUTOFIX_REPAIRABLE_STATUSES` | `400,404,422` | Which provider statuses are eligible for a repair                                                                                                                                                                                                   |
  | `AUTOFIX_HEALING_API_KEY`     | unset         | Sent as `x-api-key` to the healing service. Only relevant when provided by the hosted healing service                                                                                                                                               |
  | `AUTOFIX_REPORT_ALL_4XX`      | `false`       | Opt-in. Also report request-side 4xx errors (except `401`/`402`/`403`/`429`) from harnesses with Autofix on, as diagnostic evidence with the secret-scrubbed request body. Bodies over 256 KB are dropped, not truncated. No fix comes back from it |

  You don't need `AUTOFIX_HEALING_API_KEY`. With no key set, the install announces its anonymous install id instead. The full list of variables lives in [Environment variables](/llm-gateway/docs/llm-gateway/docs/reference/environment-variables).
</div>

## Related

* [LLM Gateway](/llm-gateway/docs/llm-gateway/docs/llm-gateway): where Autofix sits in the request flow
* [Observability](/llm-gateway/docs/llm-gateway/docs/observability): finding failing requests in the log
* [Request logs](/llm-gateway/docs/llm-gateway/docs/request-logs): reading the original and patched bodies
* [Error codes](/llm-gateway/docs/llm-gateway/docs/errors)
