# Data flow — axios/axios

> Canonical page: https://codevetter.com/unpack/axios/data-flow

# Data flow — axios/axios

Scanned commit 56a5f1acdc41965f464eb59bec6cc828113ba546 (2026-09-16). Generated by codevetter codevetter 1.12.0 on 2026-09-22.

Input boundaries are the user config object (or URL string), instance defaults, and environment state (env proxy vars, `document.cookie`, platform globals). `mergeConfig` is the single state-materialization point: it emits a **null-prototype** object with `hasOwnProperty` restored as a non-enumerable own slot, skipping `__proto__`/`constructor`/`prototype` keys entirely. `dispatchRequest` re-flattens whatever interceptors handed back via `utils.toSafeFlatObject`, normalizes headers into `AxiosHeaders`, runs `transformRequest`, then hands off to the adapter. Adapters own the outbound byte boundary (header sanitization to byte strings, body size accounting, stream piping) and produce a raw `{data, status, statusText, headers, config, request}`, which flows back through `transformResponse`, `AxiosHeaders.from`, `settle`, and finally the response interceptor chain.
- `mergeConfig` builds its result on `Object.create(null)` and re-attaches `hasOwnProperty` as a non-enumerable own data property with a `__proto__: null` descriptor, so `config.baseURL`/`config.auth` reads can never inherit from a polluted `Object.prototype` while user code calling `config.hasOwnProperty(...)` still works. — [lib/core/mergeConfig.js#L33-L46](https://github.com/axios/axios/blob/56a5f1acdc41965f464eb59bec6cc828113ba546/lib/core/mergeConfig.js#L33-L46)
- Per-key merge strategy is table-driven: `url`/`method`/`data` take config2 only, ~25 keys (`baseURL`, `timeout`, `httpAgent`, `socketPath`, `allowedSocketPaths`, …) use `defaultToConfig2`, `validateStatus` uses `mergeDirectKeys`, `headers` deep-merges caselessly after `headersToObject`, and everything unlisted falls through to `mergeDeepProperties`. — [lib/core/mergeConfig.js#L118-L159](https://github.com/axios/axios/blob/56a5f1acdc41965f464eb59bec6cc828113ba546/lib/core/mergeConfig.js#L118-L159)
- The merge loop explicitly `return`s on `__proto__`, `constructor`, and `prototype` before dispatching to a merge function, so those keys can never be materialized onto the merged config. — [lib/core/mergeConfig.js#L152-L159](https://github.com/axios/axios/blob/56a5f1acdc41965f464eb59bec6cc828113ba546/lib/core/mergeConfig.js#L152-L159)
- Headers enter via three-way flattening in `Axios._request`: `headers.common` merged with `headers[config.method]`, the per-method buckets then deleted from the raw object, and the remainder concatenated through `AxiosHeaders.concat(contextHeaders, headers)`. — [lib/core/Axios.js#L143-L154](https://github.com/axios/axios/blob/56a5f1acdc41965f464eb59bec6cc828113ba546/lib/core/Axios.js#L143-L154) [lib/core/AxiosHeaders.js#L418-L425](https://github.com/axios/axios/blob/56a5f1acdc41965f464eb59bec6cc828113ba546/lib/core/AxiosHeaders.js#L418-L425)
- `dispatchRequest` calls `utils.toSafeFlatObject(_config)` first, which flattens the config and its application-defined prototype chain into a null-prototype copy while stopping at the realm's `Object.prototype` boundary — this is the defense against an interceptor returning an ordinary (pollutable) object. — [lib/core/dispatchRequest.js#L35-L43](https://github.com/axios/axios/blob/56a5f1acdc41965f464eb59bec6cc828113ba546/lib/core/dispatchRequest.js#L35-L43) [lib/utils.js#L118-L160](https://github.com/axios/axios/blob/56a5f1acdc41965f464eb59bec6cc828113ba546/lib/utils.js#L118-L160)
- `transformData` is invoked with `config` as `this`, wraps `context.headers` in `AxiosHeaders`, calls each fn as `fn.call(config, data, headers.normalize(), status)`, and normalizes headers again afterwards — which is how `transformRequest` can mutate content-type in place. — [lib/core/transformData.js#L15-L27](https://github.com/axios/axios/blob/56a5f1acdc41965f464eb59bec6cc828113ba546/lib/core/transformData.js#L15-L27) [lib/core/dispatchRequest.js#L46](https://github.com/axios/axios/blob/56a5f1acdc41965f464eb59bec6cc828113ba546/lib/core/dispatchRequest.js#L46)
- Default `transformRequest` is a type-dispatch ladder: HTMLForm→FormData, FormData→(JSON if JSON content-type else passthrough), ArrayBuffer/Buffer/Stream/File/Blob/ReadableStream passthrough, ArrayBufferView→`.buffer`, URLSearchParams→string with urlencoded content-type, FileList→`toFormData({'files[]': …})`, plain object→`stringifySafely` with `application/json`. — [lib/defaults/index.js#L44-L108](https://github.com/axios/axios/blob/56a5f1acdc41965f464eb59bec6cc828113ba546/lib/defaults/index.js#L44-L108)
- Outbound header values are sanitized twice: `AxiosHeaders.normalizeValue` strips C0/DEL via `sanitizeHeaderValue`, and both the Node and XHR adapters additionally pass the whole header set through `toByteStringHeaderObject`, which rewrites into a null-prototype object with non-byte-string chars removed. — [lib/helpers/sanitizeHeaderValue.js#L33-L62](https://github.com/axios/axios/blob/56a5f1acdc41965f464eb59bec6cc828113ba546/lib/helpers/sanitizeHeaderValue.js#L33-L62) [lib/core/AxiosHeaders.js#L13-L18](https://github.com/axios/axios/blob/56a5f1acdc41965f464eb59bec6cc828113ba546/lib/core/AxiosHeaders.js#L13-L18) [lib/adapters/http.js#L953-L971](https://github.com/axios/axios/blob/56a5f1acdc41965f464eb59bec6cc828113ba546/lib/adapters/http.js#L953-L971)
- URL construction is a two-stage pipeline: `buildFullPath(baseURL, url, allowAbsoluteUrls, config)` combines/validates (rejecting `http:foo` style missing-`//` URLs with `ERR_INVALID_URL`), then `buildURL(fullPath, params, paramsSerializer)` appends serialized params using a custom encoder that un-escapes `:`/`$`/`,` and maps space to `+`. — [lib/core/buildFullPath.js#L45-L76](https://github.com/axios/axios/blob/56a5f1acdc41965f464eb59bec6cc828113ba546/lib/core/buildFullPath.js#L45-L76) [lib/helpers/buildURL.js#L14-L30](https://github.com/axios/axios/blob/56a5f1acdc41965f464eb59bec6cc828113ba546/lib/helpers/buildURL.js#L14-L30) [lib/helpers/resolveConfig.js#L44-L48](https://github.com/axios/axios/blob/56a5f1acdc41965f464eb59bec6cc828113ba546/lib/helpers/resolveConfig.js#L44-L48)
- URLs embedded in `ERR_INVALID_URL` messages are redacted before stringification — userinfo, query-parameter values, and fragment contents are replaced with `[REDACTED ****]` while scheme/host/path/param names survive — because `AxiosError.toJSON()` serializes `message` verbatim and `config.redact` cannot reach it. — [lib/core/buildFullPath.js#L10-L43](https://github.com/axios/axios/blob/56a5f1acdc41965f464eb59bec6cc828113ba546/lib/core/buildFullPath.js#L10-L43) [lib/core/AxiosError.js#L6](https://github.com/axios/axios/blob/56a5f1acdc41965f464eb59bec6cc828113ba546/lib/core/AxiosError.js#L6)
- Basic-auth credentials flow from either `config.auth` (read with `utils.getSafeProp`) or URL userinfo; in the Node adapter they become the `auth` option and any pre-existing `authorization` header is deleted, while in fetch/XHR they're base64-encoded into an `Authorization: Basic` header after UTF-8→Latin-1 transcoding. — [lib/adapters/http.js#L905-L920](https://github.com/axios/axios/blob/56a5f1acdc41965f464eb59bec6cc828113ba546/lib/adapters/http.js#L905-L920) [lib/adapters/fetch.js#L274-L312](https://github.com/axios/axios/blob/56a5f1acdc41965f464eb59bec6cc828113ba546/lib/adapters/fetch.js#L274-L312) [lib/helpers/resolveConfig.js#L50-L63](https://github.com/axios/axios/blob/56a5f1acdc41965f464eb59bec6cc828113ba546/lib/helpers/resolveConfig.js#L50-L63)
- Response data flows back through `settle(resolve, reject, response)`, which resolves when `validateStatus` is absent/passing and otherwise rejects with `ERR_BAD_REQUEST` for 4xx and `ERR_BAD_RESPONSE` for everything else, carrying `config`, `request`, and `response`. — [lib/core/settle.js#L14-L27](https://github.com/axios/axios/blob/56a5f1acdc41965f464eb59bec6cc828113ba546/lib/core/settle.js#L14-L27)
- `dispatchRequest` temporarily assigns `config.response` before running `transformResponse` (in both the resolve and reject paths) and deletes it in a `finally`, so a JSON-parse failure inside `transformResponse` can attach the response to the thrown `AxiosError` without permanently polluting the config. — [lib/core/dispatchRequest.js#L56-L90](https://github.com/axios/axios/blob/56a5f1acdc41965f464eb59bec6cc828113ba546/lib/core/dispatchRequest.js#L56-L90) [lib/defaults/index.js#L129-L138](https://github.com/axios/axios/blob/56a5f1acdc41965f464eb59bec6cc828113ba546/lib/defaults/index.js#L129-L138)
- The fetch adapter never trusts a caller-declared `Content-Length` for `maxBodyLength`: it computes real size with `getBodyLength` (blob size, materialized `Request.arrayBuffer().byteLength` for spec forms, `TextEncoder` bytes for strings) and counts unknown-size streams chunk-by-chunk through `trackStream`. — [lib/adapters/fetch.js#L176-L218](https://github.com/axios/axios/blob/56a5f1acdc41965f464eb59bec6cc828113ba546/lib/adapters/fetch.js#L176-L218) [lib/adapters/fetch.js#L329-L362](https://github.com/axios/axios/blob/56a5f1acdc41965f464eb59bec6cc828113ba546/lib/adapters/fetch.js#L329-L362) [lib/helpers/trackStream.js](https://github.com/axios/axios/blob/56a5f1acdc41965f464eb59bec6cc828113ba546/lib/helpers/trackStream.js)

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)
