TypeError [ERR_INVALID_URL]: Invalid URL を Node.js で修正する方法

beginner💚 Node.js2026-05-11| Node.js 10以降(Linux、macOS、Windows 全プラットフォーム)— WHATWG URL API、fetch()、および `new URL()` を使用するコードに影響

Error Message

TypeError [ERR_INVALID_URL]: Invalid URL
#nodejs#url#url-api#fetch#url-constructor

TL;DR

不正な形式または相対URLをnew URL()fetch()、またはその他の完全に有効な絶対URLを要求するAPIに渡しています。2秒で解決:URLにスキーム(https://またはhttp://)が含まれていることを確認してください。相対パスの場合は、第2引数としてベースURLを渡してください。

// 壊れている
const url = new URL('/api/users'); // TypeError [ERR_INVALID_URL]: Invalid URL

// 修正済み
const url = new URL('/api/users', 'https://example.com');
console.log(url.href); // https://example.com/api/users

根本原因

Node.jsはWHATWG URL標準に従っています。これはブラウザが使用するのと同じ仕様です。つまり、new URL(input, base?)は設計上厳格です。baseなしで相対パスを渡すと、即座に例外をスローし、一切の質問を受け付けません。

このエラーを確実に引き起こす状況は以下の通りです:

  • ベースなしの相対パス:new URL('/path')
  • URLがundefinednull、または空文字列
  • URLにスペースまたは#|などのエンコードされていない特殊文字が含まれている
  • プロトコルが欠落している:new URL('example.com/path')——有効に見えても、そうではない
  • 変数補間の失敗——文字列が予期しない内容になっている
  • Node.jsでfetch('/api/data')を呼び出す——ブラウザと異なり、Node.jsには暗黙的なベースURLのコンテキストがない

修正方法

1. 相対URL——第2引数としてベースを渡す

これは最も一般的なミスです。ブラウザにはwindow.locationという暗黙的なベースがありますが、Node.jsにはありません。明示的に指定する必要があります。

// 誤り
const u = new URL('/users/123');

// 正しい
const u = new URL('/users/123', 'https://api.example.com');
console.log(u.href); // https://api.example.com/users/123

2. URLがundefinedまたはnull

環境変数の典型的な落とし穴——変数が設定されていない場合、process.env.API_URLundefinedとなり、new URL(undefined)は即座にクラッシュします。

const endpoint = process.env.API_URL; // 設定されていない場合はundefined
new URL(endpoint); // TypeError [ERR_INVALID_URL]: Invalid URL

// 修正:使用前に検証する
if (!endpoint) throw new Error('API_URL env var is not set');
const url = new URL(endpoint);

3. プロトコルの欠落 / ホスト名のみ

api.example.com/usersは有効なURLのように見えます。しかし、明示的なスキームを必要とするWHATWGパーサーにとっては有効ではありません。

// 誤り——スキームなし
new URL('api.example.com/users');

// 正しい
new URL('https://api.example.com/users');

4. URLにスペースまたは無効な文字が含まれている

ユーザー入力や動的データから構築されたURLは、最初にエンコードする必要があります。URLSearchParamsはこれを自動的に処理します——テンプレートリテラルの代わりに使用してください。

const searchTerm = 'hello world';

// 誤り
const u = new URL(`https://example.com/search?q=${searchTerm}`);

// 正しい——URLSearchParamsが自動でエンコード
const u = new URL('https://example.com/search');
u.searchParams.set('q', searchTerm);
console.log(u.href); // https://example.com/search?q=hello+world

5. Node.jsでの相対URLを使ったfetch()

Node 18以降にはネイティブのfetch()が搭載されていますが、注意点があります:ブラウザと異なり、ベースURLがありません。Reactやブラウザでうまくいく相対パスは、ここでは失敗します。常に絶対URLを渡してください。

// Node.jsでは誤り(ブラウザでは動作するが、ここでは失敗する)
const res = await fetch('/api/data');

// 正しい
const BASE = process.env.API_URL ?? 'http://localhost:3000';
const res = await fetch(`${BASE}/api/data`);

6. ユーザー入力にはtry/catchでラップする

外部からの入力を信頼しないでください。ラップし、エラーをキャッチし、プロセスをクラッシュさせる代わりに gracefullyに失敗してください。

function parseUrl(input) {
  try {
    return new URL(input);
  } catch {
    return null; // またはより分かりやすいエラーをスロー
  }
}

const result = parseUrl(userInput);
if (!result) {
  console.error('Invalid URL provided:', userInput);
}

7. URLを動的に構築する——URL APIを適切に使用する

文字列の連結は脆弱です——余分なスラッシュやエンコードされていない文字が1つあるだけで、このエラーに戻ってしまいます。パスとクエリの構築はURL APIに任せてください。

const base = new URL('https://api.example.com');
const endpoint = new URL('/v2/users', base);
endpoint.searchParams.set('page', '2');
endpoint.searchParams.set('limit', '50');

console.log(endpoint.href);
// https://api.example.com/v2/users?page=2&limit=50

確認方法

これをcheck-url.jsというファイルに保存し、node check-url.jsで実行してください。すべての行にOK:が表示されるはずです。FAIL:の行は、どのケースがまだ壊れているかを正確に示しています。

const cases = [
  ['https://example.com/path', undefined],
  ['/relative', 'https://example.com'],
  ['https://example.com/search', undefined],
];

for (const [input, base] of cases) {
  try {
    const u = base ? new URL(input, base) : new URL(input);
    console.log('OK:', u.href);
  } catch (e) {
    console.error('FAIL:', input, '->', e.message);
  }
}

クイックチェックリスト

  • URLはhttp://またはhttps://で始まっていますか?
  • 変数は実際に文字列ですか——undefinednullではありませんか?
  • 相対パスの場合:ベースURLが第2引数として渡されていますか?
  • URLにエンコードされていないスペースまたは特殊文字はありませんか?
  • Node.jsでfetch()を使用している場合:URLは絶対URLですか?

参考資料

Related Error Notes