{"record":{"id":"23e178e3c7a66254","repo":"Mintplex-Labs/anything-llm","slug":"type-type-is-not-a-valid-type-to-sync","errorCode":null,"errorMessage":"Type \"${type}\" is not a valid type to sync.","messagePattern":"Type \"(.+?)\" is not a valid type to sync\\.","errorType":"validation","errorClass":"Error","httpStatus":200,"severity":"warning","filePath":"collector/extensions/index.js","lineNumber":22,"sourceCode":"  resolveRepoLoader,\n  resolveRepoLoaderFunction,\n} = require(\"../utils/extensions/RepoLoader\");\nconst { reqBody } = require(\"../utils/http\");\nconst { validURL, validateURL } = require(\"../utils/url\");\nconst RESYNC_METHODS = require(\"./resync\");\nconst { loadObsidianVault } = require(\"../utils/extensions/ObsidianVault\");\n\nfunction extensions(app) {\n  if (!app) return;\n\n  app.post(\n    \"/ext/resync-source-document\",\n    [verifyPayloadIntegrity, setDataSigner],\n    async function (request, response) {\n      try {\n        const { type, options } = reqBody(request);\n        if (!RESYNC_METHODS.hasOwnProperty(type))\n          throw new Error(`Type \"${type}\" is not a valid type to sync.`);\n        return await RESYNC_METHODS[type](options, response);\n      } catch (e) {\n        console.error(e);\n        response.status(200).json({\n          success: false,\n          content: null,\n          reason: e.message || \"A processing error occurred.\",\n        });\n      }\n      return;\n    }\n  );\n\n  app.post(\n    \"/ext/:repo_platform-repo\",\n    [verifyPayloadIntegrity, setDataSigner],\n    async function (request, response) {\n      try {","sourceCodeStart":4,"sourceCodeEnd":40,"githubUrl":"https://github.com/Mintplex-Labs/anything-llm/blob/526360e320da9d1b36074be5ed64fe76e5bbfbbd/collector/extensions/index.js#L4-L40","documentation":"Thrown by the /ext/resync-source-document route dispatcher in collector/extensions/index.js:22 when the `type` field on the POST body does not match any key on RESYNC_METHODS. The handler checks `RESYNC_METHODS.hasOwnProperty(type)`, so only the exact string keys exported from collector/extensions/resync/index.js are accepted: link, youtube, confluence, github, gitlab, gitea, drupalwiki, paperless-ngx. The request is still answered HTTP 200 with success:false and the message in `reason`.","triggerScenarios":"POST /ext/resync-source-document with a body whose `type` is missing, undefined, null, an empty string, a typo like \"github-file\", or a value that was never a registered resync kind (e.g. \"notion\", \"web\"/*, \"drive\"). Anything that is not one of the eight RESYNC_METHODS keys triggers it.","commonSituations":"Frontend/client sends a stale `type` after an upgrade that renamed or removed a kind; payload omits `type`; a typo in integration code; calling the resync endpoint for a document type that the collector has no re-fetch path for.","solutions":["Send `type` as one of: \"link\", \"youtube\", \"confluence\", \"github\", \"gitlab\", \"gitea\", \"drupalwiki\", \"paperless-ngx\".","Confirm the payload is JSON and that reqBody(request) actually parsed `type` (check Content-Type: application/json).","If you need a new kind, register it in collector/extensions/resync/index.js by exporting a handler and re-deploy; otherwise pick an existing type.","Read the returned `reason` field — it echoes the invalid type back so you can see exactly what the server received."],"exampleFix":"// before\nawait fetch('/ext/resync-source-document', {\n  method: 'POST',\n  body: JSON.stringify({ type: 'github-file', options: { chunkSource } }),\n});\n\n// after — use the registered key\nawait fetch('/ext/resync-source-document', {\n  method: 'POST',\n  headers: { 'Content-Type': 'application/json' },\n  body: JSON.stringify({ type: 'github', options: { chunkSource } }),\n});","handlingStrategy":"validation","validationCode":"const VALID_RESYNC_TYPES = [\n  \"link\", \"youtube\", \"confluence\",\n  \"github\", \"gitlab\", \"gitea\",\n  \"drupalwiki\", \"paperless-ngx\",\n];\nfunction isValidResyncType(type) {\n  return typeof type === \"string\" && VALID_RESYNC_TYPES.includes(type);\n}\n// before calling the API:\nif (!isValidResyncType(body.type)) {\n  throw new Error(`Unsupported resync type '${body.type}'. Valid: ${VALID_RESYNC_TYPES.join(\", \")}`);\n}","typeGuard":"/** @param {unknown} v */\nfunction isResyncType(v) {\n  return typeof v === \"string\" && Object.prototype.hasOwnProperty.call(\n    { link:1, youtube:1, confluence:1, github:1, gitlab:1, gitea:1, drupalwiki:1, \"paperless-ngx\":1 },\n    v,\n  );\n}","tryCatchPattern":"// server already returns 200 + success:false — treat the envelope as the error channel\nconst res = await fetch('/ext/resync-source-document', { method:'POST', body: JSON.stringify({ type, options }) });\nconst body = await res.json();\nif (!body.success) throw new Error(`Resync failed: ${body.reason}`);","preventionTips":["Keep the list of resync `type` keys in sync with collector/extensions/resync/index.js module.exports.","Validate the type on the client before firing the request to save a round trip.","Treat success:false in the 200 response as the error signal — the route does not return 4xx for bad types."],"tags":["api","validation","resync","request-payload"],"backgroundTag":null,"analyzedSha":"526360e320da9d1b36074be5ed64fe76e5bbfbbd","analyzedAt":"2026-08-13T01:45:47.170Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}