libnyanpasu/clash-nyanpasu · error

PAC script must contain FindProxyForURL function

Error message

PAC script must contain FindProxyForURL function

What it means

validate_pac_script performs a structural check that a PAC script is usable: it requires the string "FindProxyForURL" to be present, since every valid PAC script must define the FindProxyForURL(url, host) entry-point function the browser/proxy resolver calls. The check is deliberately lightweight — no JavaScript engine is used.

Source

Thrown at backend/tauri/src/core/pac.rs:94

    }

    /// Save PAC script to cache directory
    pub async fn save_pac_script(script: &str) -> Result<PathBuf> {
        let cache_dir = crate::utils::dirs::cache_dir()?;
        let pac_file = cache_dir.join("pac.js");

        fs::write(&pac_file, script)
            .await
            .context("failed to save PAC script")?;

        Ok(pac_file)
    }

    /// Basic validation of PAC script structure - check for required functions
    pub async fn validate_pac_script(script: &str) -> Result<()> {
        // A basic validation without using the JS engine - just check if FindProxyForURL function exists
        if !script.contains("FindProxyForURL") {
            return Err(anyhow::anyhow!(
                "PAC script must contain FindProxyForURL function"
            ));
        }

        // Additional basic checks could be added here if needed
        Ok(())
    }

    /// Set system proxy to use PAC URL
    pub fn set_pac_proxy(url: &str) -> Result<()> {
        // Check if Autoproxy is supported on this platform
        if !Autoproxy::is_support() {
            return Err(anyhow::anyhow!(
                "PAC proxy is not supported on this platform"
            ));
        }

        let autoproxy = Autoproxy {

View on GitHub (pinned to f7dbce2997)

Solutions

  1. Open the script and ensure it defines function FindProxyForURL(url, host) { ... }
  2. Re-download the script from the correct URL — the current content is likely an error page
  3. Check for typos in the function name (validation is a substring check, so the exact casing FindProxyForURL is required)
  4. Validate the full script in a browser/engine if it contains FindProxyForURL but still misbehaves
  5. Restore the default/generic PAC script if you cannot author one

Example fix

// before: script body
function findproxyforurl(url, host) { return "DIRECT"; }
// after
function FindProxyForURL(url, host) { return "DIRECT"; }
Defensive patterns

Strategy: validation

Validate before calling

fn looks_like_pac(script: &str) -> bool {
    script.contains("FindProxyForURL") && !script.trim_start().starts_with('<') // reject HTML error pages
}

Type guard

fn is_valid_pac_script(s: &str) -> bool {
    !s.trim().is_empty() && s.contains("FindProxyForURL")
}

Try / catch

match validate_pac_script(&script).await {
    Ok(()) => save_script(script),
    Err(e) => log::error!("downloaded content is not a PAC script: {e}; keeping previous script"),
}

Prevention

When it happens

Trigger: Calling validate_pac_script with content that lacks the substring FindProxyForURL — e.g. an HTML error page, an empty file, a 404 body saved as the script, or a truncated download.

Common situations: PAC URL served an error page instead of the script; user pasted wrong content into the PAC editor; script downloaded but truncated/empty; someone wrote a PAC file naming the function differently (e.g. misspelled).

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of libnyanpasu/clash-nyanpasu@f7dbce2997 (2026-09-08). Data as JSON: /api/errors/b222f91063d14b3a. Report an issue: GitHub.