sigoden/aichat · error · anyhow::Error

{err}

Error message

{err}

What it means

fetch() returns the stored CLIENT construction error when the global HTTP client failed to initialize. The bail just re-emits that stored error, so the root cause is the client's lazy initialization failure (e.g. invalid proxy settings).

Solutions

  1. Read the underlying message; fix the proxy URL in http_proxy/https_proxy/all_proxy
  2. Unset invalid proxy env vars and retry
  3. Ensure the binary was built with TLS support and valid CA certificates are installed
  4. Update the app in case of a known client-init bug

Example fix

// before: invalid proxy
export https_proxy="127.0.0.1:7890"  // missing scheme
// after
export https_proxy="http://127.0.0.1:7890"
Defensive patterns

Strategy: try-catch

Validate before calling

function validateProxyEnv() {
  for (const k of ['http_proxy', 'https_proxy', 'all_proxy']) {
    const v = process.env[k];
    if (v && !/^https?:\/\/|^socks5:\/\//.test(v)) {
      throw new Error(`${k} must be a full URL, got: ${v}`);
    }
  }
}

Try / catch

try {
  const models = await syncModels();
} catch (e) {
  // likely client init failure: check proxy env / TLS setup
  console.error('http client unavailable:', e.message);
}

Prevention

When it happens

Trigger: Calling sync_models (or any code path through fetch) when reqwest::Client could not be built at startup — commonly due to invalid HTTP(S)_PROXY/ALL_PROXY env values or TLS backend issues.

Common situations: Corporate proxy env vars set to malformed URLs; bad CA cert configuration; TLS runtime not available in the build.

Related errors


AI-assisted analysis of sigoden/aichat@82976d349a (2026-09-09). Data as JSON: /api/errors/a89fff221cdc6c6b. Report an issue: GitHub.

Appendix: source

Thrown at src/utils/request.rs:63

        (
            Regex::new(r"github.com/([^/]+)/([^/]+)/wiki").unwrap(),
            CrawlOptions {
                exclude: vec!["_history".into()],
                extract: Some("#wiki-body".into()),
                ..Default::default()
            },
        ),
    ]
});

static EXTENSION_RE: LazyLock<Regex> = LazyLock::new(|| Regex::new(r"\.[^.]+$").unwrap());
static GITHUB_REPO_RE: LazyLock<Regex> =
    LazyLock::new(|| Regex::new(r"^https://github\.com/([^/]+)/([^/]+)/tree/([^/]+)").unwrap());

pub async fn fetch(url: &str) -> Result<String> {
    let client = match *CLIENT {
        Ok(ref client) => client,
        Err(ref err) => bail!("{err}"),
    };
    let res = client.get(url).send().await?;
    let output = res.text().await?;
    Ok(output)
}

pub async fn fetch_with_loaders(
    loaders: &HashMap<String, String>,
    path: &str,
    allow_media: bool,
) -> Result<(String, String)> {
    if let Some(loader_command) = loaders.get(URL_LOADER) {
        let contents = run_loader_command(path, URL_LOADER, loader_command)?;
        return Ok((contents, DEFAULT_EXTENSION.into()));
    }
    let client = match *CLIENT {
        Ok(ref client) => client,
        Err(ref err) => bail!("{err}"),

View on GitHub (pinned to 82976d349a)