Mintplex-Labs/anything-llm · error · Error

HTTP

Error message

HTTP ${res.status}: ${res.statusText}

What it means

QDrant.namespaceExists(client, namespace) throws on a falsy namespace instead of returning false. This is asymmetric with its public wrapper hasNamespace(), which returns false for falsy input without throwing. The throw therefore signals a programming error at the call site: an internal caller passed an empty/missing namespace where a boolean answer was expected.

Solutions

  1. Use hasNamespace(namespace) for user-supplied or possibly-empty values — it returns a boolean and never throws for falsy input.
  2. When calling namespaceExists directly, validate first: typeof namespace === 'string' && namespace.length > 0.
  3. Trace the null back to its source (reqBody destructuring, slug generation) and fix it there.
  4. Cover internal helpers with a unit test asserting the guard so signature drift is caught early.

Example fix

// before
const exists = await qdrant.namespaceExists(client, maybeNull);

// after
const exists = maybeNull && (await qdrant.hasNamespace(maybeNull));
// or, if you must call the internal helper:
if (!namespace) throw new Error('namespace required before existence check');
const exists = await qdrant.namespaceExists(client, namespace);
Defensive patterns

Strategy: type-guard

Validate before calling

const isNonEmpty = (ns) => typeof ns === 'string' && ns.trim().length > 0;
if (!isNonEmpty(namespace)) {
  return false; // same semantics as hasNamespace: falsy namespace means 'no'
}
const exists = await qdrant.namespaceExists(client, namespace);

Type guard

async function collectionExists(qdrantDB, client, namespace) {
  if (typeof namespace !== 'string' || namespace.length === 0) return false; // never call namespaceExists with falsy
  return await qdrantDB.namespaceExists(client, namespace);
}

Try / catch

try {
  const exists = await qdrant.namespaceExists(client, namespace);
} catch (e) {
  if (/No namespace value provided/.test(e.message)) {
    // contract violation upstream: normalize instead of throwing where a boolean was expected
    return false;
  }
  throw e;
}

Prevention

When it happens

Trigger: Direct calls like namespaceExists(client, null) or namespaceExists(client) (default null); performSimilaritySearch / namespace-stats paths only reach it after their own guards, so hitting this throw means custom code or a refactor bypassed validation; passing an empty-string slug produced by a bad slugify.

Common situations: Custom integrations calling provider internals; code that assumed namespaceExists tolerates null like hasNamespace does; upstream refactors that reordered arguments.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of Mintplex-Labs/anything-llm@3aec848f28 (2026-08-18). Data as JSON: /api/errors/36e709cadff8752f. Report an issue: GitHub.

Appendix: source

Thrown at collector/utils/downloadURIToFile/index.js:46

 * @returns {Promise<{success: boolean, fileLocation: string|null, reason: string|null}>} - The path to the downloaded file
 */
async function downloadURIToFile(url, maxTimeout = 10_000) {
  if (!url || typeof url !== "string" || !validURL(url))
    return { success: false, reason: "Not a valid URL.", fileLocation: null };

  try {
    const abortController = new AbortController();
    const timeout = setTimeout(() => {
      abortController.abort();
      console.error(
        `Timeout ${maxTimeout}ms reached while downloading file for URL:`,
        url.toString()
      );
    }, maxTimeout);

    const res = await fetch(url, { signal: abortController.signal })
      .then((res) => {
        if (!res.ok) throw new Error(`HTTP ${res.status}: ${res.statusText}`);
        return res;
      })
      .finally(() => clearTimeout(timeout));

    const urlObj = new URL(url);
    const sluggedPath = slugify(urlObj.pathname, { lower: true });
    let filename = `${urlObj.hostname}-${sluggedPath}`;

    const existingExt = path.extname(filename).toLowerCase();
    const { SUPPORTED_FILETYPE_CONVERTERS } = require("../constants");

    // If the filename does not already have a supported file extension,
    // try to infer one from the response Content-Type header.
    // This handles URLs like https://arxiv.org/pdf/2307.10265 where the
    // path has no explicit extension but the server responds with
    // Content-Type: application/pdf.
    if (!SUPPORTED_FILETYPE_CONVERTERS.hasOwnProperty(existingExt)) {
      const { parseContentType } = require("../../processLink/helpers");

View on GitHub (pinned to 3aec848f28)