Mintplex-Labs/anything-llm · warning · Error
Not a valid URL.
Error message
Not a valid URL.
What it means
Thrown by the /ext/website-depth route in collector/extensions/index.js:131 after running the user-supplied URL through validateURL() then validURL(). validURL returns false when the URL cannot be parsed by the URL constructor, its protocol is not http: or https:, or its hostname is a private/loopback-style IP octet (10/127/169/172/192) unless COLLECTOR_ALLOW_ANY_IP is set. The handler answers HTTP 400 with success:false.
Source
Thrown at collector/extensions/index.js:131
data: {
title: null,
author: null,
},
});
}
return;
}
);
app.post(
"/ext/website-depth",
[verifyPayloadIntegrity],
async function (request, response) {
try {
const websiteDepth = require("../utils/extensions/WebsiteDepth");
const { url, depth = 1, maxLinks = 20 } = reqBody(request);
const validatedUrl = validateURL(url);
if (!validURL(validatedUrl)) throw new Error("Not a valid URL.");
const scrapedData = await websiteDepth(validatedUrl, depth, maxLinks);
response.status(200).json({ success: true, data: scrapedData });
} catch (e) {
console.error(e);
response.status(400).json({ success: false, reason: e.message });
}
return;
}
);
app.post(
"/ext/confluence",
[verifyPayloadIntegrity, setDataSigner],
async function (request, response) {
try {
const { loadConfluence } = require("../utils/extensions/Confluence");
const { success, reason, data } = await loadConfluence(
reqBody(request),View on GitHub (pinned to 526360e320)
Solutions
- Send a fully-qualified http(s) URL, e.g. "https://example.com".
- If you must crawl a private/LAN IP, start the collector with COLLECTOR_ALLOW_ANY_IP=true (intentional admin opt-in).
- Trim/encode the URL on the client before sending.
- Confirm the field name is exactly `url` in the JSON body.
Example fix
// before
fetch('/ext/website-depth', { method: 'POST', body: JSON.stringify({ url: '10.0.0.5:8080/docs' }) });
// after
fetch('/ext/website-depth', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ url: 'http://10.0.0.5:8080/docs', depth: 2 }),
});
// and on the collector host: COLLECTOR_ALLOW_ANY_IP=true Defensive patterns
Strategy: validation
Validate before calling
const { validURL, validateURL } = require("./utils/url");
function safeWebsiteDepthInput(url) {
const validated = validateURL(url);
if (!validURL(validated)) {
return { ok: false, reason: `Not a valid URL: ${url}` };
}
return { ok: true, url: validated };
}
const check = safeWebsiteDepthInput(input.url);
if (!check.ok) return respondBadRequest(check.reason); Type guard
/** @param {unknown} u */
function isHttpUrlString(u) {
if (typeof u !== "string" || u.length === 0) return false;
try {
const parsed = new URL(u.includes("://") ? u : `https://${u}`);
return ["http:", "https:"].includes(parsed.protocol);
} catch { return false; }
} Try / catch
try {
const res = await fetch('/ext/website-depth', { method:'POST', body: JSON.stringify({ url, depth, maxLinks }) });
if (!res.ok) {
const { reason } = await res.json();
throw new Error(`website-depth failed (${res.status}): ${reason}`);
}
return await res.json();
} catch (e) {
// distinguish validation (400) from network
if (/Not a valid URL/.test(e.message)) surfaceUserError(e.message);
throw e;
} Prevention
- Always normalize the URL with validateURL before sending.
- For private/LAN targets, set COLLECTOR_ALLOW_ANY_IP intentionally and document why.
- Never send a bare string with spaces or no protocol — validateURL tries to fix it but validURL can still reject private IPs.
When it happens
Trigger: POST /ext/website-depth where `url` is empty, not a string, has a non-http protocol (ftp://, file://), is malformed ("example com"), or points at a private IP like 10.0.0.5 while COLLECTOR_ALLOW_ANY_IP is not enabled.
Common situations: User pastes a bare domain without protocol and validateURL's URL() constructor still rejects it; pointing the depth crawler at an intranet/private-LAN address; passing a URL with embedded spaces or unicode that the URL parser throws on; sending `url` as null/undefined from the UI.
Related errors
- Type "${type}" is not a valid type to sync.
- Invalid link provided
- Invalid source property provided
- "${azureOpenAiEndpoint}" is not a valid URL. Check your sett
AI-assisted analysis of Mintplex-Labs/anything-llm@526360e320 (2026-08-13).
Data as JSON: /api/errors/df1557b30c44bc1d.
Report an issue: GitHub.