# Behavior traces — unjs/ofetch

> Canonical page: https://codevetter.com/unpack/ofetch/behavior-traces

# Behavior traces — unjs/ofetch

Scanned commit 1dbc37fd1ceab832fc7c90cad81b1091c95ba563 (2026-07-08). Generated by codevetter codevetter 1.15.0 on 2026-10-02.

Source inspection; upstream code and tests were not executed.

Source reading followed initialization, a JSON POST, and HTTP failure with retry through their complete call chains. Additional branches cover custom clients, streaming, and transport rejection. The same raw function owns preprocessing, fetch, decoding, hooks, and status handling. These are static execution traces rather than observed runs.
- Initialization proceeds index.ts → base.ts exports → entrypoint fetch wrapper → createFetch({ fetch }) → ofetch/$fetch aliases; unsupported global fetch uses the rejecting wrapper. — [src/index.ts#L1-L15](https://github.com/unjs/ofetch/blob/1dbc37fd1ceab832fc7c90cad81b1091c95ba563/src/index.ts#L1-L15) [src/base.ts#L1-L2](https://github.com/unjs/ofetch/blob/1dbc37fd1ceab832fc7c90cad81b1091c95ba563/src/base.ts#L1-L2) [src/fetch.ts#L36-L37](https://github.com/unjs/ofetch/blob/1dbc37fd1ceab832fc7c90cad81b1091c95ba563/src/fetch.ts#L36-L37) [src/fetch.ts#L259-L279](https://github.com/unjs/ofetch/blob/1dbc37fd1ceab832fc7c90cad81b1091c95ba563/src/fetch.ts#L259-L279)
- A JSON POST proceeds $fetch → $fetchRaw → resolveFetchOptions → uppercase method → onRequest → withBase/withQuery → isJSONSerializable → JSON.stringify and default headers. — [examples/body.mjs#L3-L9](https://github.com/unjs/ofetch/blob/1dbc37fd1ceab832fc7c90cad81b1091c95ba563/examples/body.mjs#L3-L9) [src/fetch.ts#L93-L153](https://github.com/unjs/ofetch/blob/1dbc37fd1ceab832fc7c90cad81b1091c95ba563/src/fetch.ts#L93-L153) [src/fetch.ts#L259-L262](https://github.com/unjs/ofetch/blob/1dbc37fd1ceab832fc7c90cad81b1091c95ba563/src/fetch.ts#L259-L262) [src/utils.ts#L17-L42](https://github.com/unjs/ofetch/blob/1dbc37fd1ceab832fc7c90cad81b1091c95ba563/src/utils.ts#L17-L42)
- After POST preparation, fetch runs → response type is selected → response text is parsed into _data → onResponse runs → status is checked → $fetch returns _data. — [src/fetch.ts#L180-L184](https://github.com/unjs/ofetch/blob/1dbc37fd1ceab832fc7c90cad81b1091c95ba563/src/fetch.ts#L180-L184) [src/fetch.ts#L200-L221](https://github.com/unjs/ofetch/blob/1dbc37fd1ceab832fc7c90cad81b1091c95ba563/src/fetch.ts#L200-L221) [src/fetch.ts#L235-L262](https://github.com/unjs/ofetch/blob/1dbc37fd1ceab832fc7c90cad81b1091c95ba563/src/fetch.ts#L235-L262)
- A qualifying 408 response is decoded first → onResponse → onResponseError → onError → retry budget/status check → optional retryDelay → recursive $fetchRaw with retry decremented. — [src/fetch.ts#L49-L75](https://github.com/unjs/ofetch/blob/1dbc37fd1ceab832fc7c90cad81b1091c95ba563/src/fetch.ts#L49-L75) [src/fetch.ts#L208-L221](https://github.com/unjs/ofetch/blob/1dbc37fd1ceab832fc7c90cad81b1091c95ba563/src/fetch.ts#L208-L221) [src/fetch.ts#L235-L254](https://github.com/unjs/ofetch/blob/1dbc37fd1ceab832fc7c90cad81b1091c95ba563/src/fetch.ts#L235-L254) [test/index.test.ts#L270-L295](https://github.com/unjs/ofetch/blob/1dbc37fd1ceab832fc7c90cad81b1091c95ba563/test/index.test.ts#L270-L295)
- When retry is unavailable or exhausted, onError calls createFetchError, optionally trims the V8 stack, and throws an error exposing URL, status, context, and decoded body. — [src/fetch.ts#L79-L86](https://github.com/unjs/ofetch/blob/1dbc37fd1ceab832fc7c90cad81b1091c95ba563/src/fetch.ts#L79-L86) [src/error.ts#L24-L63](https://github.com/unjs/ofetch/blob/1dbc37fd1ceab832fc7c90cad81b1091c95ba563/src/error.ts#L24-L63)
- A transport rejection sets context.error → awaits onRequestError → enters onError; AbortError suppresses automatic retry only when timeout is absent. — [src/fetch.ts#L39-L49](https://github.com/unjs/ofetch/blob/1dbc37fd1ceab832fc7c90cad81b1091c95ba563/src/fetch.ts#L39-L49) [src/fetch.ts#L185-L193](https://github.com/unjs/ofetch/blob/1dbc37fd1ceab832fc7c90cad81b1091c95ba563/src/fetch.ts#L185-L193) [test/index.test.ts#L298-L310](https://github.com/unjs/ofetch/blob/1dbc37fd1ceab832fc7c90cad81b1091c95ba563/test/index.test.ts#L298-L310)
- Client creation proceeds $fetch.create → shallow global/default merging → createFetch; later calls independently merge headers and query through resolveFetchOptions. — [src/fetch.ts#L268-L277](https://github.com/unjs/ofetch/blob/1dbc37fd1ceab832fc7c90cad81b1091c95ba563/src/fetch.ts#L268-L277) [src/utils.ts#L94-L118](https://github.com/unjs/ofetch/blob/1dbc37fd1ceab832fc7c90cad81b1091c95ba563/src/utils.ts#L94-L118) [test/index.test.ts#L347-L382](https://github.com/unjs/ofetch/blob/1dbc37fd1ceab832fc7c90cad81b1091c95ba563/test/index.test.ts#L347-L382)
- An SSE response follows content-type detection → stream branch → response.body or _bodyInit assigned to _data → caller receives the stream and reads chunks itself. — [src/utils.ts#L72-L76](https://github.com/unjs/ofetch/blob/1dbc37fd1ceab832fc7c90cad81b1091c95ba563/src/utils.ts#L72-L76) [src/fetch.ts#L224-L227](https://github.com/unjs/ofetch/blob/1dbc37fd1ceab832fc7c90cad81b1091c95ba563/src/fetch.ts#L224-L227) [src/fetch.ts#L259-L262](https://github.com/unjs/ofetch/blob/1dbc37fd1ceab832fc7c90cad81b1091c95ba563/src/fetch.ts#L259-L262) [README.md#L297-L306](https://github.com/unjs/ofetch/blob/1dbc37fd1ceab832fc7c90cad81b1091c95ba563/README.md#L297-L306)

Every claim links to its cited files at the pinned commit. Citations identify source evidence; they do not establish runtime correctness. Independent CodeVetter scan — not reviewed by upstream maintainers.

## Public product links

- [CodeVetter](https://codevetter.com/)
- [Download](https://codevetter.com/download)
- [Documentation](https://codevetter.com/docs/)
- [Source](https://github.com/Codevetter/codevetter)
