Skip to content

fix: support URL object as config.url input#10866

Merged
jasonsaayman merged 8 commits into
axios:v1.xfrom
Liuwei1125:fix/url-object-v2
May 9, 2026
Merged

fix: support URL object as config.url input#10866
jasonsaayman merged 8 commits into
axios:v1.xfrom
Liuwei1125:fix/url-object-v2

Conversation

@Liuwei1125
Copy link
Copy Markdown
Contributor

@Liuwei1125 Liuwei1125 commented May 8, 2026

Summary

Fixes the crash when passing a URL object as the URL input to axios.

Problem

When calling axios.get(new URL('http://example.com/foo')) or axios.get(new URL('/foo', 'http://example.com')) with a baseURL, axios crashed because:

  1. isAbsoluteURL returned false for URL objects (typeof check)
  2. combineURLs called .replace() on the URL object which doesn't exist
  3. buildFullPath passed the raw URL object to combineURLs

Fix

  • Move URL object coercion from buildURL to Axios._request before mergeConfig. This ensures all downstream consumers (buildFullPath, combineURLs, adapters) see a string.
  • Remove the broken unit test buildURL(url, null) that never exercised URL coercion (it early-returns before the coercion code)
  • Add e2e tests via the HTTP adapter covering URL object with params and URL object without params

Review feedback

Addresses @jasonsaayman's feedback:

  1. Moved coercion to Axios.js so it covers all crash paths, not just buildURL
  2. Replaced broken unit test with proper e2e tests using mock HTTP adapter

Summary by cubic

Fixes crashes when passing a URL object to axios by normalizing config.url to a string across the whole pipeline and widening types to string | URL. Covers interceptor-modified URLs, adds a buildURL safeguard, and updates docs.

Description

  • Summary of changes

    • Coerce config.url when it is a URL in Axios._request, dispatchRequest (pre/post transforms), and getUri.
    • Safeguard buildURL to coerce URL-like inputs for direct callers.
    • Update type defs to allow string | URL for all method overloads and AxiosRequestConfig.url.
    • Add README note and example under axios(url[, config]).
    • Detection does not rely on global URL being a constructor; uses a tag-based check.
  • Reasoning

    • Previous code called string methods on URL objects (e.g., .replace, .indexOf), causing crashes with or without baseURL and when interceptors set config.url.
  • Additional context

    • Normalization happens early and before adapter selection so all paths (buildFullPath, combineURLs, transforms, adapters) see a string.

Docs

  • Update /docs/ to note config.url supports string | URL and include a short example mirroring the README.

Testing

  • Added HTTP adapter e2e tests for URL inputs (with existing query + params, and without params).
  • Added unit tests for:
    • buildURL with URL and URL-like objects.
    • Shorthand axios(urlObj, config), getUri({ url: URL }).
    • Interceptors setting config.url to a URL.
    • Environments where global URL is not a constructor.
  • Removed the incorrect test that didn’t exercise coercion.

Semantic version impact

  • Patch: bug fix and type widening without breaking changes.

Written for commit e23b357. Summary will update on new commits.

liuwei53 added 2 commits May 6, 2026 16:59
Fixes axios#6546

When passing a URL object (e.g., new URL(...)) to axios methods
like axios.get(url, { params: {...} }), the buildURL function
would crash with 'url.indexOf is not a function' because it assumed
url was always a string.

This fix converts URL objects to strings before processing.
- Move URL object coercion from buildURL to Axios._request so that all
  downstream consumers (buildFullPath, combineURLs, adapters) see a string.
  This fixes the crash when using URL object with baseURL (combineURLs
  calls .replace() on the URL object).
- Remove the broken buildURL unit test that tested buildURL(url, null)
  without actually exercising URL coercion (buildURL early-returns when
  !params).
- Add e2e tests via the HTTP adapter for URL object with params and
  URL object without params (no crash).
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 4 files

Confidence score: 5/5

  • Automated review surfaced no issues in the provided summaries.
  • No files require special attention.

@jasonsaayman jasonsaayman added priority::medium A medium priority commit::fix The PR is related to a bugfix labels May 9, 2026
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

4 issues found across 7 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="lib/helpers/buildURL.js">

<violation number="1" location="lib/helpers/buildURL.js:32">
P3: Custom agent: **Flag AI Slop and Fabricated Changes**

Comment references a non-existent `./unsafe/buildURL` path, which is misleading and looks like fabricated change text.</violation>

<violation number="2" location="lib/helpers/buildURL.js:34">
P2: URL coercion is now too narrow; non-native or cross-realm URL-like objects can reach string methods and crash.</violation>

<violation number="3" location="lib/helpers/buildURL.js:34">
P2: `url instanceof URL` can throw when `URL` exists but is not a callable constructor.</violation>
</file>

<file name="index.d.cts">

<violation number="1" location="index.d.cts:476">
P1: Broadening `url` to `string | URL` leaks into internal interceptor config, but the runtime only normalizes before interceptors run. An interceptor can reintroduce a `URL` object and send it downstream unnormalized.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Comment thread index.d.cts

interface AxiosRequestConfig<D = any> {
url?: string;
url?: string | URL;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: Broadening url to string | URL leaks into internal interceptor config, but the runtime only normalizes before interceptors run. An interceptor can reintroduce a URL object and send it downstream unnormalized.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At index.d.cts, line 476:

<comment>Broadening `url` to `string | URL` leaks into internal interceptor config, but the runtime only normalizes before interceptors run. An interceptor can reintroduce a `URL` object and send it downstream unnormalized.</comment>

<file context>
@@ -473,7 +473,7 @@ declare namespace axios {
 
   interface AxiosRequestConfig<D = any> {
-    url?: string;
+    url?: string | URL;
     method?: Method | string;
     baseURL?: string;
</file context>

Comment thread lib/helpers/buildURL.js Outdated
Comment thread lib/helpers/buildURL.js Outdated
Comment thread lib/helpers/buildURL.js Outdated
@jasonsaayman
Copy link
Copy Markdown
Member

@cubic-dev-ai please review this one again!

@cubic-dev-ai
Copy link
Copy Markdown
Contributor

cubic-dev-ai Bot commented May 9, 2026

@cubic-dev-ai please review this one again!

@jasonsaayman I have started the AI code review. It will take a few minutes to complete.

Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 9 files

Confidence score: 5/5

  • Automated review surfaced no issues in the provided summaries.
  • No files require special attention.

@jasonsaayman jasonsaayman merged commit 847d89b into axios:v1.x May 9, 2026
23 checks passed
@DigitalBrainJS
Copy link
Copy Markdown
Collaborator

DigitalBrainJS commented May 10, 2026

@jasonsaayman
I have to put in my two cents as the code is not clean and overly complex, and this negatively affects bundle size.

  • We have kindof utility to detect object class.
  • Previously, we didn't support urls that weren't strings, so writing additional code that would preserve the original url type if it isn't a URL object is pretty pointless.
    const normalizeURL = (url) => (isURL(url) ? url.toString() : url);
    does the same as
    String(url)
    It's unclear why we have duplicate code for isURL and normalizeURL in both Axios.js and dispatchRequest.js files.
  • In addition, we call isURL twice here:
const normalizeURL = (url) => (isURL(url) ? url.toString() : url);

function normalizeConfigURL(config) {
  if (isURL(config.url)) {
    config.url = normalizeURL(config.url);
  }
}
  • We introduce a breaking change in typings as url is no longer guaranteed to be a string in InternalAxiosRequestConfig,
  • url argument in the buildURL is always defined, so
/**
 * Build a URL by appending params to the end
 *
 * @param {string} url The base of the url (e.g., http://www.google.com)
 */
export default function buildURL(url, params, options) {
  // Safeguard for direct callers (e.g. via ./unsafe/helpers/buildURL.js): coerce URL-like
  // objects to strings before using string methods below.
  if (url !== null && typeof url === 'object' && typeof url.toString === 'function') {
    url = url.toString();
  }

is equal to url = String(url);

@jasonsaayman
Copy link
Copy Markdown
Member

jasonsaayman commented May 10, 2026

Thanks @DigitalBrainJS, this one is on me I maybe went to heavily handed with review suggestions. I have reverted this, and we can think about URL object support, maybe in a future release.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

commit::fix The PR is related to a bugfix priority::medium A medium priority

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants