{"record":{"id":"6045f1e4cfed17a7","repo":"Stirling-Tools/Stirling-PDF","slug":"invalid-folder-scanning-config-pipeline-index-6045f1","errorCode":null,"errorMessage":"Invalid folder scanning config: pipeline[${index}].operation must be a non-empty string","messagePattern":"Invalid folder scanning config: pipeline\\[(.+?)\\]\\.operation must be a non-empty string","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"frontend/editor/src/core/utils/automationConverter.ts","lineNumber":252,"sourceCode":"  const pipeline = obj.pipeline;\n  if (!Array.isArray(pipeline)) {\n    throw new Error(\"Invalid folder scanning config: missing 'pipeline' array\");\n  }\n\n  const endpointMap = buildEndpointToToolIdMap(toolRegistry);\n  const unresolved: string[] = [];\n\n  const operations: AutomationOperation[] = pipeline.map(\n    (step: unknown, index: number) => {\n      if (!step || typeof step !== \"object\") {\n        throw new Error(\n          `Invalid folder scanning config: pipeline[${index}] is not an object`,\n        );\n      }\n      const stepObj = step as Record<string, unknown>;\n      const rawOperation = stepObj.operation;\n      if (typeof rawOperation !== \"string\" || rawOperation.length === 0) {\n        throw new Error(\n          `Invalid folder scanning config: pipeline[${index}].operation must be a non-empty string`,\n        );\n      }\n      const rawParameters = (stepObj.parameters as Record<string, any>) || {};\n      // Strip the export-time marker so the imported automation runs cleanly.\n      const { fileInput: _fileInput, ...parameters } = rawParameters;\n\n      // 1) Direct frontend-tool-id match (handles the converter's fallback when\n      //    no endpoint could be resolved at export time).\n      if (isToolIdInRegistry(rawOperation, toolRegistry)) {\n        return { operation: rawOperation, parameters };\n      }\n\n      // 2) Static endpoint string match.\n      const staticMatch = endpointMap.get(rawOperation);\n      if (staticMatch) {\n        return { operation: staticMatch, parameters };\n      }","sourceCodeStart":234,"sourceCodeEnd":270,"githubUrl":"https://github.com/Stirling-Tools/Stirling-PDF/blob/9ef20dcab80b85041912f045e17a6aea1d08f969/frontend/editor/src/core/utils/automationConverter.ts#L234-L270","documentation":"Thrown when a pipeline step's operation field is missing, not a string, or empty. operation must be a non-empty string (an endpoint path or frontend tool id).","triggerScenarios":"step.operation is undefined, null, a number, or an empty string.","commonSituations":"A typo (e.g. 'Operation'); a step with only parameters; an export from an incompatible tool version that omitted the operation field.","solutions":["Ensure each step has a non-empty string operation.","Re-export the config.","Validate each step against a schema before mapping."],"exampleFix":"// before\nif (typeof rawOperation !== 'string' || rawOperation.length === 0) throw new Error('operation must be a non-empty string');\n\n// after\nconst schema = { operation: 'string' };\nconst ok = pipeline.every((s) => typeof s?.operation === 'string' && s.operation.length > 0);\nif (!ok) throw new Error('Each pipeline step needs a non-empty operation string.');","handlingStrategy":"validation","validationCode":"const bad = pipeline.findIndex((s) => typeof (s as any)?.operation !== 'string' || !(s as any).operation);\nif (bad !== -1) throw new Error(`pipeline[${bad}].operation must be a non-empty string`);","typeGuard":"function stepHasOperation(s: unknown): s is { operation: string } {\n  return !!s && typeof (s as any).operation === 'string' && (s as any).operation.length > 0;\n}","tryCatchPattern":null,"preventionTips":["Schema-validate imported configs (e.g. with zod) before running them.","Treat operation as the load-bearing field and validate it first."],"tags":["automation","config","validation","json","folder-scanning"],"backgroundTag":null,"analyzedSha":"9ef20dcab80b85041912f045e17a6aea1d08f969","analyzedAt":"2026-08-13T22:11:39.827Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}