{"record":{"id":"97aee544a2b58b4c","repo":"Stirling-Tools/Stirling-PDF","slug":"no-automation-configuration-provided","errorCode":null,"errorMessage":"No automation configuration provided","messagePattern":"No automation configuration provided","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"frontend/editor/src/core/hooks/tools/automate/useAutomateOperation.ts","lineNumber":22,"sourceCode":"} from \"@app/hooks/tools/shared/useToolOperation\";\nimport { useCallback } from \"react\";\nimport { executeAutomationSequence } from \"@app/utils/automationExecutor\";\nimport { useToolRegistry } from \"@app/contexts/ToolRegistryContext\";\nimport { AutomateParameters } from \"@app/types/automation\";\n\nexport function useAutomateOperation() {\n  const { allTools } = useToolRegistry();\n  const toolRegistry = allTools;\n\n  const customProcessor = useCallback(\n    async (params: AutomateParameters, files: File[]) => {\n      console.log(\"🚀 Starting automation execution via customProcessor\", {\n        params,\n        files,\n      });\n\n      if (!params.automationConfig) {\n        throw new Error(\"No automation configuration provided\");\n      }\n\n      // Execute the automation sequence and return the final results\n      const finalResults = await executeAutomationSequence(\n        params.automationConfig!,\n        files,\n        toolRegistry,\n        (stepIndex: number, operationName: string) => {\n          console.log(`Step ${stepIndex + 1} started: ${operationName}`);\n          params.onStepStart?.(stepIndex, operationName);\n        },\n        (stepIndex: number, resultFiles: File[]) => {\n          console.log(\n            `Step ${stepIndex + 1} completed with ${resultFiles.length} files`,\n          );\n          params.onStepComplete?.(stepIndex, resultFiles);\n        },\n        (stepIndex: number, error: string) => {","sourceCodeStart":4,"sourceCodeEnd":40,"githubUrl":"https://github.com/Stirling-Tools/Stirling-PDF/blob/9ef20dcab80b85041912f045e17a6aea1d08f969/frontend/editor/src/core/hooks/tools/automate/useAutomateOperation.ts#L4-L40","documentation":"Thrown by the automate tool's customProcessor when `params.automationConfig` is falsy. The automate tool is a multi-step pipeline driver; it requires a structured automationConfig (the ordered step list) to call `executeAutomationSequence`. Without it there is nothing to execute, so it refuses rather than running zero steps silently.","triggerScenarios":"The automate operation was invoked (e.g. via a saved automation, a deep link, or programmatic dispatch) without an automationConfig attached to params; a UI race where the user clicked 'Run' before the automation builder produced a config; a deserialization gap that dropped automationConfig from params.","commonSituations":"Automation builder UI submitted with zero steps; deep-linked automation whose config failed to load; automation triggered from code/tests without constructing the config object.","solutions":["Disable the 'Run automation' button until automationConfig is non-null and has at least one step.","Construct the automationConfig in the caller and assert its shape before invoking the operation.","Guard with an earlier validation in the parameter schema (validateParams) so the error surfaces at validation time with a field-level message."],"exampleFix":"// before\nif (!params.automationConfig) {\n  throw new Error(\"No automation configuration provided\");\n}\n\n// after — validate at the schema boundary with a human message\nconst cfg = params.automationConfig;\nif (!cfg || cfg.steps.length === 0) {\n  throw new Error(\"No automation configuration provided: add at least one step before running.\");\n}","handlingStrategy":"validation","validationCode":"// Ensure automationConfig exists and has steps before invoking\nconst cfg = params.automationConfig;\nif (!cfg || !Array.isArray(cfg.steps) || cfg.steps.length === 0) {\n  // do not run; show 'add at least one step' UI\n}","typeGuard":"function isValidAutomationConfig(c: unknown): c is { steps: unknown[] } {\n  return !!c && typeof c === \"object\" && Array.isArray((c as { steps?: unknown[] }).steps) && (c as { steps: unknown[] }).steps.length > 0;\n}","tryCatchPattern":null,"preventionTips":["Disable the 'Run automation' button until automationConfig is present with at least one step.","Validate automationConfig shape in the tool's validateParams so missing config surfaces as a field error.","Construct automationConfig in one place and assert its shape before passing it to the operation."],"tags":["automation","validation","tool-pipeline"],"backgroundTag":null,"analyzedSha":"9ef20dcab80b85041912f045e17a6aea1d08f969","analyzedAt":"2026-08-13T22:11:39.827Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}