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

# Autofix

> Repair a malformed request and resend it once, before the fallback chain runs. Turn it on per harness.

<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, Manifest 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](/docs/llm-gateway#fallback).

Renamed models are covered through the provider itself. When a request names a model Manifest hasn't catalogued but the provider and credentials are unambiguous, Manifest 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. Manifest normalizes the error into a
    message, type, and parameter.
  </Step>

  <Step title="Manifest 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">
    Manifest 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, Manifest 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 Manifest's hosted healing 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/Dni3Y170DaoBJ3h5/images/autofix-connect-harness.png?fit=max&auto=format&n=Dni3Y170DaoBJ3h5&q=85&s=7be0e41a8d0b29e115e272a139ce350d" alt="The Connect Harness modal with the Autofix toggle switched on under the name field" width="1330" height="1328" data-path="images/autofix-connect-harness.png" />
</Frame>

### Harnesses you already have

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

<div data-deploy="cloud">
  On Manifest 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/Dni3Y170DaoBJ3h5/images/autofix-settings-toggle.png?fit=max&auto=format&n=Dni3Y170DaoBJ3h5&q=85&s=11136da5e230d6e6ee4c7c452532d1ff" alt="A harness's Settings page with the Autofix failing requests toggle switched on" width="1634" height="1506" data-path="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/Dni3Y170DaoBJ3h5/images/autofix-enable-modal.png?fit=max&auto=format&n=Dni3Y170DaoBJ3h5&q=85&s=628ded7bb41ddc9dbe8ecbdb0e72cb26" alt="The Enable Autofix modal listing harnesses that have Autofix off, each with its own toggle" width="1376" height="1188" data-path="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](/docs/reference/telemetry) uses.
</div>

When Autofix repairs a request, Manifest 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 Manifest 500.
* **A slow healer stops being asked.** After three consecutive transport failures, Manifest 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, Manifest 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/Dni3Y170DaoBJ3h5/images/autofix-request-panel.png?fit=max&auto=format&n=Dni3Y170DaoBJ3h5&q=85&s=d94a5b22b611f8e6fbd71eba4584cb26" alt="The request drawer on a repaired request, with the failed and patched attempts listed and the Autofix panel showing what changed" width="3024" height="1716" data-path="images/autofix-request-panel.png" />
</Frame>

The failed original and its patched retry are separate [provider attempts](/docs/observability#requests-and-provider-attempts), so with [request logs](/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                                                         |
| ------------------------ | ------------------------------------------------------------------------ |
| **Request 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                 |

Each card links through to the matching filter on the request log.

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

  <Note>
    Self-hosted only. On [Manifest 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 if Manifest issues you one                                                                                                                                                                |
  | `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](/docs/reference/environment-variables).
</div>

## Related

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