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
- Use hasNamespace(namespace) for user-supplied or possibly-empty values — it returns a boolean and never throws for falsy input.
- When calling namespaceExists directly, validate first: typeof namespace === 'string' && namespace.length > 0.
- Trace the null back to its source (reqBody destructuring, slug generation) and fix it there.
- 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
- Remember the asymmetry: hasNamespace(null) returns false; namespaceExists(client, null) throws — prefer the public wrapper.
- Type-check the namespace before every namespaceExists call.
- Trace falsy values to their source (destructuring defaults, slugify output) rather than catching downstream.
- Add lint/test coverage on internal call sites that pass user input.
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
- The native whisper model failed to download from the…
- res.statusText || "Error generating api key."
- Namespace by that name does not exist.
- res.statusText || "Error fetching api keys."
- Empty entry
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)