{"record":{"id":"1a28aaed01174bf9","repo":"Stirling-Tools/Stirling-PDF","slug":"invalid-folder-scanning-config-missing-pipeline","errorCode":null,"errorMessage":"Invalid folder scanning config: missing 'pipeline' array","messagePattern":"Invalid folder scanning config: missing 'pipeline' array","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"frontend/editor/src/core/utils/automationConverter.ts","lineNumber":236,"sourceCode":" * Parse a folder-scanning pipeline JSON into the native AutomationConfig\n * shape. Endpoint paths are reverse-mapped to frontend tool IDs via the\n * supplied registry; unmappable operations are kept verbatim and reported in\n * `unresolvedOperations`.\n */\nexport function parseFolderScanningConfig(\n  raw: unknown,\n  toolRegistry: Partial<ToolRegistry>,\n): {\n  automation: Omit<AutomationConfig, \"id\" | \"createdAt\" | \"updatedAt\">;\n  unresolvedOperations: string[];\n} {\n  if (!raw || typeof raw !== \"object\") {\n    throw new Error(\"Invalid folder scanning config: expected JSON object\");\n  }\n  const obj = raw as Record<string, unknown>;\n  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        );","sourceCodeStart":218,"sourceCodeEnd":254,"githubUrl":"https://github.com/Stirling-Tools/Stirling-PDF/blob/9ef20dcab80b85041912f045e17a6aea1d08f969/frontend/editor/src/core/utils/automationConverter.ts#L218-L254","documentation":"Thrown by parseFolderScanningConfig when the value is an object but obj.pipeline is not an array. The folder-scanning format requires a top-level pipeline array.","triggerScenarios":"The object has no pipeline key, pipeline is an object/string instead of an array, or an Automate-format file (operations[]) was parsed as folder-scanning.","commonSituations":"User hand-edited the export and renamed/removed pipeline; importing an Automate JSON as folder-scanning; a typo in the key.","solutions":["Confirm the file has a top-level \"pipeline\": [...] array.","Use auto-detect (omit expectedFormat) so the correct parser is chosen.","Re-export the config from the Automate tool."],"exampleFix":"// before\nconst pipeline = obj.pipeline;\nif (!Array.isArray(pipeline)) throw new Error('missing pipeline array');\n\n// after\nif (detectAutomationFormat(raw) !== 'folderScanning') {\n  throw new Error('This file is not a folder-scanning config.');\n}","handlingStrategy":"validation","validationCode":"if (detectAutomationFormat(raw) !== 'folderScanning') {\n  throw new Error('File is not folder-scanning format (no pipeline array).');\n}","typeGuard":"function hasPipelineArray(raw: unknown): boolean {\n  return !!raw && typeof raw === 'object' && !Array.isArray(raw)\n    && Array.isArray((raw as any).pipeline);\n}","tryCatchPattern":null,"preventionTips":["Let detectAutomationFormat pick the parser instead of forcing a format.","Document that folder-scanning exports use 'pipeline' and Automate exports use 'operations'."],"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"}