GopeedLab/gopeed · error · WebViewRpcException

NAVIGATION_FAILED

NAVIGATION_FAILED

Error message

e.toString()

What it means

Thrown by WebViewRpcPageSession.goto (webview_rpc_service.dart:416) when controller.loadUrl itself throws before navigation starts. This is the native flutter_inappwebview layer rejecting the URLRequest — e.g. a URL that cannot be parsed into a WebUri — not a network failure (those arrive later via onReceivedError, error 35). The pending navigation completer is cleared and the raw exception string is wrapped as NAVIGATION_FAILED.

Source

Thrown at ui/flutter/lib/app/rpc/webview_rpc_service.dart:416

      } catch (_) {
        // Best-effort only for the current page. The user script persists
        // for future navigations through the native user script registry.
      }
    }
  }

  Future<void> goto(String url, {int? timeoutMs, String? waitUntil}) async {
    final controller = await _controllerOrThrow();
    final waitStrategy = _normalizeWaitUntil(waitUntil);
    final navigation = _ensureNavigationCompleter();
    try {
      await controller.loadUrl(urlRequest: URLRequest(url: WebUri(url)));
    } catch (e) {
      if (identical(_navigation, navigation)) {
        _navigation = null;
      }
      throw WebViewRpcException(
        code: 'NAVIGATION_FAILED',
        message: e.toString(),
      );
    }
    final future = switch (waitStrategy) {
      'domcontentloaded' => Future.any<void>([
          _waitForDomReady(),
          navigation.future,
        ]),
      _ => navigation.future,
    };
    if (timeoutMs == null || timeoutMs <= 0) {
      await future;
      return;
    }
    await future.timeout(
      Duration(milliseconds: timeoutMs),
      onTimeout: () {
        _navigation = null;

View on GitHub (pinned to 7b7327ffb3)

Solutions

  1. Inspect the message: e.toString() contains the native error (e.g. PlatformException or URI parse failure) which names the real cause
  2. Normalize and percent-encode the URL before sending, and default the scheme to https:// when missing
  3. Restrict goto targets to http/https URLs you have validated with Uri.tryParse
  4. If the page was closed concurrently, reopen the page and retry once

Example fix

// before
await page.goto(rawHref); // rawHref may be '/relative/path' or contain spaces

// after
final base = Uri.parse(currentOrigin);
final target = base.resolve(rawHref.trim().replaceAll(' ', '%20'));
await page.goto(target.toString());
Defensive patterns

Strategy: try-catch

Validate before calling

function normalizeUrl(href, base) {
  try {
    const u = base ? new URL(href, base) : new URL(href);
    if (u.protocol !== 'http:' && u.protocol !== 'https:') throw new Error('unsupported scheme');
    return u.toString();
  } catch {
    throw new TypeError(`invalid goto url: ${href}`);
  }
}

Type guard

function isHttpUrl(s) {
  try { const u = new URL(s); return u.protocol === 'http:' || u.protocol === 'https:'; }
  catch { return false; }
}

Try / catch

try {
  await page.goto(url);
} catch (e) {
  if (e.code === 'NAVIGATION_FAILED') {
    // message holds the native exception; fix URL or reopen page, then retry once
    if (!isHttpUrl(url)) throw new TypeError('bad url');
    await reopenAndGoto(url);
  } else throw e;
}

Prevention

When it happens

Trigger: Calling 'page.goto' with url: '' is caught earlier (_string), but urls like 'ftp://x', 'not a url', 'file:///nonexistent', or a URL with illegal control characters make WebUri/loadUrl throw. Also occurs when the underlying platform webview is in an invalid state.

Common situations: Passing a scheme the platform cannot load; building URLs by string concatenation that produces spaces or bad characters; embedded control characters from scraped HTML; WebView version changes tightening URL validation.

Related errors


AI-assisted analysis of GopeedLab/gopeed@7b7327ffb3 (2026-08-16). Data as JSON: /api/errors/fa8a5d6ee0f31e68. Report an issue: GitHub.