{"record":{"id":"1d9b00d4dcfbc933","repo":"Mintplex-Labs/anything-llm","slug":"invalid-link-provided","errorCode":null,"errorMessage":"Invalid link provided","messagePattern":"Invalid link provided","errorType":"validation","errorClass":"Error","httpStatus":200,"severity":"warning","filePath":"collector/extensions/resync/index.js","lineNumber":9,"sourceCode":"const { getLinkText } = require(\"../../processLink\");\n\n/**\n * Fetches the content of a raw link. Returns the content as a text string of the link in question.\n * @param {object} data - metadata from document (eg: link)\n * @param {import(\"../../middleware/setDataSigner\").ResponseWithSigner} response\n */\nasync function resyncLink({ link }, response) {\n  if (!link) throw new Error(\"Invalid link provided\");\n  try {\n    const { success, content = null, reason } = await getLinkText(link);\n    if (!success) throw new Error(`Failed to sync link content. ${reason}`);\n    response.status(200).json({ success, content });\n  } catch (e) {\n    console.error(e);\n    response.status(200).json({\n      success: false,\n      content: null,\n    });\n  }\n}\n\n/**\n * Fetches the content of a YouTube link. Returns the content as a text string of the video in question.\n * We offer this as there may be some videos where a transcription could be manually edited after initial scraping\n * but in general - transcriptions often never change.\n * @param {object} data - metadata from document (eg: link)","sourceCodeStart":1,"sourceCodeEnd":27,"githubUrl":"https://github.com/Mintplex-Labs/anything-llm/blob/526360e320da9d1b36074be5ed64fe76e5bbfbbd/collector/extensions/resync/index.js#L1-L27","documentation":"Thrown by resyncLink in collector/extensions/resync/index.js:9 when the destructured `link` field from the document metadata is falsy. The resync-source-document dispatcher catches it and still returns HTTP 200 with success:false and content:null, so the error is surfaced to the caller as a failed re-sync, not an HTTP error.","triggerScenarios":"POST /ext/resync-source-document with { type: \"link\", options: {} } or with options.link set to \"\", null, or undefined. Typically the document metadata row no longer has a stored link or the client passed the wrong shape.","commonSituations":"A previously scraped web-page document lost its `link` metadata; integration code passes the document object directly instead of { link }; a DB migration stripped the field.","solutions":["Send options as { link: \"<full http(s) URL>\" }.","Confirm the source document metadata actually has a non-empty `link` value before issuing resync.","If the document is not link-based, pick the correct `type` (e.g. \"youtube\", \"github\")."],"exampleFix":"// before\nRESYNC_METHODS.link({}, response);\n\n// after\nRESYNC_METHODS.link({ link: \"https://example.com/article\" }, response);","handlingStrategy":"validation","validationCode":"function requireLink(options) {\n  if (!options || typeof options.link !== \"string\" || options.link.trim().length === 0) {\n    throw new Error(\"Invalid link provided\");\n  }\n  return options.link;\n}\nconst link = requireLink(options); // call before the API","typeGuard":"/** @param {{link?: unknown}} o */\nfunction hasNonEmptyLink(o) {\n  return o != null && typeof o.link === \"string\" && o.link.trim().length > 0;\n}","tryCatchPattern":"// The dispatcher returns 200 + success:false — check the envelope\nconst result = await resyncLink({ link }, response);\nif (result && result.success === false) handleMissingContent(result);","preventionTips":["Persist the original `link` on document metadata so resync always has it.","Distinguish 'document has no link metadata' from 'fetch failed' by validating client-side first.","Pass options as a plain object literal — destructuring on undefined throws differently."],"tags":["validation","resync","link","request-payload"],"backgroundTag":null,"analyzedSha":"526360e320da9d1b36074be5ed64fe76e5bbfbbd","analyzedAt":"2026-08-13T01:45:47.170Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}