Mintplex-Labs/anything-llm · error · Error

Failed to sync link content. ${reason}

Error message

Failed to sync link content. ${reason}

What it means

Thrown by resyncLink in collector/extensions/resync/index.js:12 when getLinkText(link) resolves with success:false. getLinkText itself returns success:false when its own validURL check fails (bad URL / private IP / non-http protocol) — see collector/processLink/index.js:36 — or when the downstream scrapeGenericUrl fails. The interpolated `reason` carries the upstream cause. The handler catches and answers HTTP 200 with success:false, content:null.

Source

Thrown at collector/extensions/resync/index.js:12

const { getLinkText } = require("../../processLink");

/**
 * Fetches the content of a raw link. Returns the content as a text string of the link in question.
 * @param {object} data - metadata from document (eg: link)
 * @param {import("../../middleware/setDataSigner").ResponseWithSigner} response
 */
async function resyncLink({ link }, response) {
  if (!link) throw new Error("Invalid link provided");
  try {
    const { success, content = null, reason } = await getLinkText(link);
    if (!success) throw new Error(`Failed to sync link content. ${reason}`);
    response.status(200).json({ success, content });
  } catch (e) {
    console.error(e);
    response.status(200).json({
      success: false,
      content: null,
    });
  }
}

/**
 * Fetches the content of a YouTube link. Returns the content as a text string of the video in question.
 * We offer this as there may be some videos where a transcription could be manually edited after initial scraping
 * but in general - transcriptions often never change.
 * @param {object} data - metadata from document (eg: link)
 * @param {import("../../middleware/setDataSigner").ResponseWithSigner} response
 */
async function resyncYouTube({ link }, response) {

View on GitHub (pinned to 526360e320)

Solutions

  1. Inspect the appended `reason` in the error — it is the upstream failure cause.
  2. Verify the URL still loads from the collector host (curl from the container).
  3. If the URL is a private/LAN resource, set COLLECTOR_ALLOW_ANY_IP=true.
  4. Retry after transient network failures; for persistent 404, remove or re-add the document.
Defensive patterns

Strategy: retry

Validate before calling

const { validURL, validateURL } = require("./utils/url");
function canResyncLink(link) {
  const v = validateURL(link);
  return { ok: validURL(v), url: v };
}
// reject early if the URL itself is the problem (most common upstream reason)
const pre = canResyncLink(link);
if (!pre.ok) return skip("link not valid for resync");

Try / catch

// reason is interpolated — match prefix, not exact text
try { await resyncLink({ link }, response); }
catch (e) {
  if (e.message.startsWith("Failed to sync link content.")) {
    const upstream = e.message.replace("Failed to sync link content. ", "");
    if (/ENOTFOUND|ETIMEDOUT|ECONNRESET|5\d\d/.test(upstream)) scheduleRetry();
    else markDocumentUnsyncable(upstream);
  }
}

Prevention

When it happens

Trigger: Resyncing a link whose stored URL is now invalid, points at a private IP without COLLECTOR_ALLOW_ANY_IP, returns 4xx/5xx, times out, or has certificate/SSRF issues; or the target page no longer exists (404/410).

Common situations: External site went offline or was moved; corporate firewall blocks the collector egress; site now sits behind a private IP; SSL cert expired; rate-limited.

Related errors


AI-assisted analysis of Mintplex-Labs/anything-llm@526360e320 (2026-08-13). Data as JSON: /api/errors/3ab35bc535d65fa6. Report an issue: GitHub.