{"record":{"id":"6086741d30222f4d","repo":"Stirling-Tools/Stirling-PDF","slug":"invalid-automation-config-missing-operations-ar","errorCode":null,"errorMessage":"Invalid automation config: missing 'operations' array","messagePattern":"Invalid automation config: missing 'operations' array","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"frontend/editor/src/core/utils/automationConverter.ts","lineNumber":322,"sourceCode":"/**\n * Parse a native Automate JSON file (a previously-exported AutomationConfig).\n * The id / createdAt / updatedAt fields are dropped — the storage layer\n * regenerates them on save.\n */\nexport function parseAutomationConfigJson(\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 automation config: expected JSON object\");\n  }\n  const obj = raw as Record<string, unknown>;\n  const operations = obj.operations;\n  if (!Array.isArray(operations)) {\n    throw new Error(\"Invalid automation config: missing 'operations' array\");\n  }\n\n  const unresolved: string[] = [];\n  const parsedOperations: AutomationOperation[] = operations.map(\n    (op: unknown, index: number) => {\n      if (!op || typeof op !== \"object\") {\n        throw new Error(\n          `Invalid automation config: operations[${index}] is not an object`,\n        );\n      }\n      const opObj = op as Record<string, unknown>;\n      const operation = opObj.operation;\n      if (typeof operation !== \"string\" || operation.length === 0) {\n        throw new Error(\n          `Invalid automation config: operations[${index}].operation must be a non-empty string`,\n        );\n      }\n      const parameters = (opObj.parameters as Record<string, any>) || {};","sourceCodeStart":304,"sourceCodeEnd":340,"githubUrl":"https://github.com/Stirling-Tools/Stirling-PDF/blob/9ef20dcab80b85041912f045e17a6aea1d08f969/frontend/editor/src/core/utils/automationConverter.ts#L304-L340","documentation":"Thrown by parseAutomationConfigJson when the value is an object but obj.operations is not an array. The Automate format requires a top-level operations array.","triggerScenarios":"The object has no operations key, operations is not an array, or a folder-scanning file (pipeline[]) was parsed as Automate.","commonSituations":"Hand-edit removed/renamed operations; importing a folder-scanning file as Automate; a typo in the key.","solutions":["Confirm the file has a top-level \"operations\": [...] array.","Use auto-detect (omit expectedFormat).","Re-export the config from the Automate tool."],"exampleFix":"// before\nif (!Array.isArray(operations)) throw new Error('missing operations array');\n\n// after\nif (detectAutomationFormat(raw) !== 'automate') {\n  throw new Error('File is not Automate format (no operations array).');\n}","handlingStrategy":"validation","validationCode":"if (detectAutomationFormat(raw) !== 'automate') {\n  throw new Error('File is not Automate format.');\n}","typeGuard":"function hasOperationsArray(raw: unknown): boolean {\n  return !!raw && typeof raw === 'object' && !Array.isArray(raw)\n    && Array.isArray((raw as any).operations);\n}","tryCatchPattern":null,"preventionTips":["Let detectAutomationFormat choose the parser.","Document the operations-vs-pipeline distinction for users."],"tags":["automation","config","validation","json"],"backgroundTag":null,"analyzedSha":"9ef20dcab80b85041912f045e17a6aea1d08f969","analyzedAt":"2026-08-13T22:11:39.827Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}