Mintplex-Labs/anything-llm · error · Error

Not a valid URL.

Error message

Not a valid URL.

What it means

connect() calls client.describeIndex(PINECONE_INDEX) and throws when status.ready is falsy. Pinecone reports ready=true only once an index is fully provisioned and servable; a freshly created index (especially serverless or pod-based) spends seconds to minutes in an initializing state. This is a startup race between index creation and first use, not an authentication problem.

Solutions

  1. Wait 30-60 seconds (serverless) or a few minutes (pods) after index creation, then retry the operation — readiness is transient.
  2. Check the index state directly: Pinecone console, or `curl -H "Api-Key: $PINECONE_API_KEY" https://api.pinecone.io/indexes/$PINECONE_INDEX` and confirm status.state is 'Ready'.
  3. Verify PINECONE_INDEX points at the intended, fully provisioned index in the same project as the API key.
  4. Wrap first-use connect() in a bounded retry-with-backoff loop that only retries on 'not ready' and rethrows everything else.

Example fix

// before
const conn = await pinecone.connect(); // throws during provisioning

// after - retry only the transient 'not ready' case
async function connectWhenReady(db, tries = 12) {
  for (let i = 0; i < tries; i++) {
    try {
      return await db.connect();
    } catch (e) {
      if (!/not ready/i.test(e.message)) throw e;
      await new Promise((r) => setTimeout(r, 5_000));
    }
  }
  throw new Error('Pinecone index still not ready after retry window');
}
Defensive patterns

Strategy: retry

Validate before calling

import { Pinecone } from '@pinecone-database/pinecone';

const pc = new Pinecone({ apiKey: process.env.PINECONE_API_KEY });
const desc = await pc.describeIndex(process.env.PINECONE_INDEX).catch(() => null);
if (!desc?.status?.ready) {
  // index still provisioning — do not call connect()/embed yet
  throw new Error(`Index not ready (state: ${desc?.status?.state ?? 'unknown'})`);
}

Type guard

async function isPineconeIndexReady(pc, indexName) {
  const d = await pc.describeIndex(indexName).catch(() => null);
  return d?.status?.ready === true;
}

Try / catch

const MAX_TRIES = 10;
for (let i = 0; i < MAX_TRIES; i++) {
  try {
    return await pineconeDB.connect();
  } catch (e) {
    if (!/not ready/i.test(e.message)) throw e; // only the transient case retries
    await new Promise((r) => setTimeout(r, 5_000 * (i + 1)));
  }
}
throw new Error('Pinecone index never became ready');

Prevention

When it happens

Trigger: Creating a Pinecone index and immediately embedding documents or calling /api/ext/vectors/heartbeat; embedding right after recreating an index with the same name; hitting an index that Pinecone lists in a non-Ready lifecycle state (initializing, failed, paused); first embed after a fresh deploy pointed at a brand-new index.

Common situations: Infrastructure scripts that create-then-load without waiting; index recreated during migration/restore; Pinecone control-plane slowness during provisioning; a wrong PINECONE_INDEX name that resolves to a different, not-yet-ready index in the account.

Related errors


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

Appendix: 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 3aec848f28)