nikivdev/code · error

typesense returned {}

Error message

typesense returned {}

What it means

typesense_search performs an HTTP POST to the configured Typesense search endpoint. Any non-2xx response status aborts with 'typesense returned <status>'. The error surfaces the HTTP status so the developer can diagnose auth, collection, or query problems on the Typesense server side.

Source

Thrown at src/install.rs:690

        .timeout(std::time::Duration::from_secs(5))
        .build()?;
    let url = format!(
        "{}/collections/{}/documents/search",
        config.url.trim_end_matches('/'),
        config.collection
    );
    let payload = serde_json::json!({
        "q": query,
        "query_by": "pkg_path,description",
        "per_page": 200,
    });
    let mut request = client.post(url).json(&payload);
    if !config.api_key.is_empty() {
        request = request.header("X-TYPESENSE-API-KEY", &config.api_key);
    }
    let response = request.send().context("failed to query typesense")?;
    if !response.status().is_success() {
        bail!("typesense returned {}", response.status());
    }
    let body: TypesenseSearchResponse = response
        .json()
        .context("failed to parse typesense response")?;
    let mut entries = Vec::new();
    for hit in body.hits {
        entries.push(FloxDisplayEntry {
            pkg_path: hit.document.pkg_path,
            description: hit.document.description,
            version: hit.document.version,
            alias: None,
        });
    }
    Ok(entries)
}

fn typesense_ensure_collection(config: &TypesenseConfig) -> Result<()> {
    let client = Client::builder()

View on GitHub (pinned to a747e741ae)

Solutions

  1. Check the HTTP status in the message: 401/403 -> fix api_key; 404 -> run_index to create the collection; 5xx -> check Typesense server health
  2. Verify TypesenseConfig (base URL, port 8108, collection, api_key)
  3. Curl the Typesense endpoint directly with the same key and query to reproduce
  4. Ensure the collection exists and is populated via run_index

Example fix

// before (no key configured -> 401)
let mut request = client.post(url).json(&payload);
// after (key set, header applied)
if !config.api_key.is_empty() {
    request = request.header("X-TYPESENSE-API-KEY", &config.api_key);
}
Defensive patterns

Strategy: retry

Validate before calling

// preflight: confirm Typesense is reachable and key valid
let health = reqwest::get(format!("{}/health", base)).await?;
if !health.status().is_success() {
    bail!("typesense unreachable before search");
}

Try / catch

match typesense_search(&config, query) {
    Err(e) if e.to_string().starts_with("typesense returned") => {
        eprintln!("Typesense rejected the query ({}); falling back to flox CLI", e);
        // fall back to flox_search_with_aliases
    }
    other => other?,
}

Prevention

When it happens

Trigger: The Typesense server responds with 4xx/5xx: bad/missing API key (401), unknown collection (404), malformed query payload (400), or server outage (5xx).

Common situations: Wrong or expired X-TYPESENSE-API-KEY; collection name mismatch in TypesenseConfig; Typesense host/port wrong or behind a proxy returning errors; index not yet built for the queried collection.

Related errors


AI-assisted analysis of nikivdev/code@a747e741ae (2026-09-01). Data as JSON: /api/errors/d3ee0358e233f580. Report an issue: GitHub.