I’m trying to automate a multi-step task on macOS by combining the Shortcuts app with AppleScript, but the workflow isn’t passing data or triggering actions consistently. I need help structuring the automation and troubleshooting how Shortcuts and AppleScript work together.
Treat AppleScript as a function, not a separate macro. In the Run AppleScript action, accept Shortcuts input with on run {input, parameters} and explicitly return the result, then feed that output into the next action using its Magic Variable instead of relying on the clipboard. Put Quick Look actions between steps to see where the data changes type or becomes empty. If app control fails despite correct data, check macOS Automation and Accessibility permissions for Shortcuts, since those often cause the “works sometimes” behavior.
Keep the boundary between Shortcuts and AppleScript narrow. Pass plain text, numbers, or a file path rather than a mixed list of files, dictionaries, and app objects. If the script needs several values, send JSON or tab-separated text and parse it there. @greenlogic is right about returning output, but many “random” failures are really type conversions at that boundary.
You should expect the data handoff to be reliable, but UI-driven app control will never be perfectly deterministic. If the AppleScript uses System Events, keystrokes, menu clicks, or assumes a window is already open, the failure may have nothing to do with Shortcuts input.
Split the workflow by responsibility: let Shortcuts gather files, ask for values, and route the result. Let AppleScript handle a single app-specific operation. If that operation depends on the interface, activate the app and wait for the required window or process instead of inserting a fixed two-second delay. Fixed waits eventually fail on a slow launch, a large document, or a permission prompt.
I’d make script errors visible too. Wrap the app-control section in try/on error, then return something like ERROR: <message> (<number>) so the next Shortcuts action can stop or show an alert. Otherwise a failed command can look like an empty output, which sends you debugging in the wrong direction.
One more caveat: test the Shortcut from the same place you plan to run it. Running inside the editor, from Finder Quick Actions, from the menu bar, and from another Shortcut can produce different input or app-focus conditions. Get the Shortcut reliable with a saved sample input first, then wire in the real trigger.
A Shortcut that just hands text to a script keeps working for months, while the same setup that reaches into an app’s menus breaks the first time that app updates its layout. That’s the split @cyberguru pointed at, and it’s real. If you ever plan to fire this from a time-based automation with the screen locked, drop the UI scripting entirely, because System Events keystrokes just quietly do nothing there.
The hidden failure mode is partial success. Shortcuts may think the run failed after AppleScript already created the file, sent the message, or changed the app. Running it again then duplicates the work.
Give each run an ID and make the script check whether that ID was already processed. Return a tiny status contract such as:
return 'OK|' & runID & '|' & resultPath
or:
return 'ERROR|' & runID & '|' & errNumber & '|' & errMessage
Then have Shortcuts split that text and branch on OK or ERROR. Don’t merely display the error and continue, since the next action may happily treat it as real data.
@cyberguru’s point about testing from the actual trigger matters here. Pass the run ID, input path, and requested operation explicitly. That makes retries predictable and avoids depending on window state, clipboard contents, or whatever Finder happened to select. A boring input/output contract beats a clever workflow.
Start by changing the handoff from “pass the data” to “pass where the data lives.” Shortcuts variables are fine for a title or a number, but multiline text, file objects, and larger payloads are much less predictable once AppleScript starts coercing them. Write the input to a temporary file, pass its POSIX path plus an output path, then let AppleScript read and write those files.
That is less elegant than a chain of Magic Variables, but easier to inspect and rerun. You can open the exact input file when something fails, and the script can write its result atomically before returning a small status such as OK|/path/to/output. Keep the status short, since delimiter-based responses become fragile when error messages or filenames contain the delimiter.
I would still keep simple values inline. The useful dividing line is payload versus control: paths, operation names, and IDs travel through Shortcuts; document contents stay in files. This avoids a surprising amount of type-conversion debugging without forcing the whole workflow into AppleScript.
Returning an ERROR|... string still tells Shortcuts that the AppleScript action completed successfully. That is fine for recoverable outcomes, but for a failure that must stop the workflow, raise an AppleScript error instead:
on run {input, parameters}
if input is {} then error 'Expected one input item' number 1001
try
-- Perform the app-specific operation here
return 'result'
on error errText number errNum
error errText number errNum
end try
end run
Then configure the Shortcut’s error handling around that action rather than letting an error-shaped string flow into the next step. Use returned status data only when Shortcuts genuinely needs to branch and recover.
Validate the input immediately too. Check whether you received zero, one, or several items before coercing anything to text. A surprising number of inconsistent workflows are really “single item during testing, list of items from the actual trigger” problems. Keep prompts and recovery choices in Shortcuts, and make the AppleScript either return the promised result type or fail loudly.