Workflow Connectors

Workflow Connectors

PrintFactory Workflow · Building a flow

Connectors

Connectors are the arrows that join one component to the next. They decide where a job goes after each step, and which jobs are allowed to go there.

In short: a connector starts at a result socket on a component (the small labelled tabs, usually OK and Fail) and ends on the component that should run next. Leave its condition empty and every job takes the route; add a condition and only matching jobs take it. Where several connectors leave the same socket, each is checked independently: the job follows the first one that accepts it, and a copy of the job is created for every other one that also accepts. If a socket has connectors but none accepts, the job stops and is reported as a problem job.

What a connector does

A flow is a set of components joined by connectors: an input, a few preparation steps, and a printer or an export. The components do the work; the connectors decide the order and carry the job from one to the next, along with its files, its job data and its history. A connector never changes a job. Only components do that.

Each connector has four parts:

PartWhat it means
Where it startsA result socket on the component the job has just finished, such as OK or Fail. Connectors always start at a socket, never at the component as a whole.
Where it endsThe component that runs next. You drop the arrow onto the component itself, because components have several results but only one way in.
NameA label for the route, such as Retail or Oversize. Names appear in the job history and can be found with the canvas search box.
ConditionAn optional test that decides whether a job may take this route. No condition means every job takes it.

Result sockets

Every component shows its result sockets as small labelled tabs along the bottom of its panel on the canvas. Which sockets a component offers is fixed by what the component does, and you cannot add or rename them.

SocketYou will see it onIt means
OKEvery componentThe step finished successfully.
FailMost components, including the inputs, Preflight, Printer, Cutter, Layout, Nester, Database and JavaScriptThe step could not process the job. A job leaving through Fail is in an error state. See What happens when a job reaches a branch.
ErrorWebhookThe same idea as Fail, named differently on that component.
FixedPreflightThe file passed, but only after Preflight corrected it, so corrected work can be routed differently from clean work.
Handled, FilledJigA part-filled jig and a completed jig, so each can take its own route.
Sockets first, conditions second. The socket already tells you how the step ended. Add a condition only when jobs that ended the same way still need separating by customer, size, material or urgency.

Drawing, changing and deleting connectors

Stop the flow before you make changes. While a flow is running you can open a connector but not change it: the Condition window is read-only and offers only Close. Stop the flow, make the change, then start it again.

Draw a connector

  1. Press and hold on the result socket you want to leave from.
  2. Drag across to the component that should run next.
  3. Release over that component.

Releasing anywhere else creates nothing. If that socket already connects to that component, Workflow selects the existing connector instead of adding a second one.

Change where a connector goes

Drag the start of the arrow onto a different socket, or drag the arrow head onto a different component. Both ends can be moved without losing the connector's name or condition, so you can re-route a branch without rebuilding it.

Open a connector

Double-click the arrow to open its Condition window.

Delete a connector

Select it and press Delete. If it holds a condition, Workflow asks you to confirm and offers Copy Script, which puts the condition on the clipboard before it is removed. Deleting a component deletes all of its connectors too, with the same warning.

Find a connector in a large flow

The canvas search box matches connector names as well as component names, and highlights what it finds. It can only find connectors that have been named, which is one more reason to name every route that carries a condition.

Choosing which jobs take a route

Double-click a connector to open the Condition window. Give the route a name, then choose how the test is described:

OptionUse it when
Match RulesYou are comparing job data or file properties such as customer, size, file type or approval status. Rules are built from drop-down lists, with no scripting, and they are checked as you build them. The right choice for almost every flow.
Run ScriptThe test needs calculation, text handling, dates, or several pieces of data combined in a way rules cannot express. Requires basic JavaScript.

A name is required before you can save, and in Run Script mode OK stays greyed out until the script is not empty. Both versions are stored, so you can switch between the two without losing your work. Only the option selected when you press OK is used when jobs run.

Turning rules into a script. Switching from Match Rules to Run Script offers to generate the script from the rules you have already built. It is the quickest way to start a complicated condition, and a good way to see exactly how a rule is being read.

Building rules

Each rule reads left to right: what to look at, which value, how to compare it, what to compare it with. The buttons at the end of the row add a rule (+), remove it (-) or nest it inside a new group ([...]).

A group header reads All of the following rules or Any of the following rules, and groups can be nested inside other groups, which is enough for tests like "approved, and either a PDF or larger than 100 MB". The full list of what you can look at and how you can compare it is in the Rule reference below.

Document rules cover every file in the job. A job can carry more than one file, and a document rule is true only when it is true for all of them. Document Type Is pdf rejects a job in which a single file is a TIFF.

A worked example

Orders arrive with a Destination of either Retail or Wholesale, and each is resized differently. Draw two connectors from the same OK socket:

Connector nameRuleGoes to
RetailKeyword · Destination · Is · RetailResize 600 × 400
WholesaleKeyword · Destination · Is · WholesaleResize 300 × 200

The two rules can never both be true, so each job takes exactly one route. An order with any other value, such as retail in lower case, a blank or a typo, matches neither and is reported as a problem job, which is usually the right outcome for an order that was not filled in correctly.

Check that the data exists first. A rule about a value the job does not carry can never be true. Where a value is optional, put Exists and your comparison in the same All group.

Writing a script

A script condition is a short JavaScript function that answers one question: should this job take this route? Return true to accept it, false to reject it.

function () {
return Key.Destination === 'Retail' && Documents.length === 1;
}

The function runs once per job, per connector, with the job's data available to it. The Script reference below lists everything you can read; console.log() writes to the Workflow log and is the simplest way to see what your script actually received.

Keep scripts to yes or no. A connector script can change the job's keywords, and changing the copy count will duplicate parts of the job. Make changes in a JavaScript component instead, where anyone reading the canvas can see that something is being changed. If a script fails, whether from a typo or from data it did not expect, the job is reported as a problem job rather than quietly skipping the route.

What happens when a job reaches a branch

When a component finishes, Workflow takes the socket that matches the outcome and checks each connector leaving it.

SituationWhat happens to the job
Nothing is connected to that socketThe route ends here. The job is finished, or reported as a problem job if it came out of a Fail socket.
One connector accepts itIt continues to that component.
Several connectors accept itThe job takes the first route, and a copy of the job is created for each of the others. Each copy then runs independently, with its own history.
No connector accepts itThe job stops and is reported as a problem job, with the message no further valid connections.
Connectors are not "if, otherwise". Every connector on the socket is checked, whatever the ones before it decided. Two conditions that can both be true produce two jobs, which is useful when you meant it and confusing when you did not. Where exactly one route must be taken, the conditions must not overlap.

Jobs that have already gone wrong follow two extra rules:

  • A problem job can only continue through a Fail socket. Once it does, it is treated as a normal job again from that point on.
  • A problem job that reaches an OK socket stops there, even if a connector would have accepted it.

Routes are checked in the order the connectors were drawn, which is not shown on the canvas. Never rely on that order to give one branch priority. Put the priority in the conditions instead.

Seeing which route a job took. When a connector with a condition accepts a job, its name is written into that job's history, so you can open any job and read the decisions it went through. While testing, switch the flow into debugging: jobs then pause after every connector, and you can inspect or edit their data before letting them continue.

Ways people use connectors

Sending work down different routes

Several connectors from one OK socket, each testing the same value for a different result such as customer, product or material. Keep the conditions mutually exclusive so each job takes one route.

Catching anything unexpected

There is no automatic "everything else" route. If unusual jobs should be looked at rather than reported as problems, add one more connector whose condition covers what the other routes do not, and send it to a hot folder, a Webhook or a manual step. Letting the job fail instead is a perfectly good design when an unknown value means the order data is wrong.

Doing two things with one job

Two connectors that both accept the same job give you two jobs on purpose: one prints, the other is exported or reported to your MIS. Each copy is a complete job in its own right.

Bringing routes back together

Any number of connectors can end on the same component, so branches prepared differently can rejoin a shared nester, printer or export.

Not missing failures

Connect the Fail socket of the components that matter to a Webhook or a hot folder, so a failure raises a notification instead of waiting quietly in the problem list.

What connectors cannot do

  • An input component starts a flow, so nothing can connect into it.
  • A component cannot connect to itself.
  • The same socket cannot have two connectors to the same component.
  • Connectors start at a socket and end on a component: several results out, one way in.
  • Connectors can only be changed while the flow is stopped.
  • A condition decides routing only. It cannot change what a component does, and anything it writes affects later steps only.
Printers and cutters are not always the end. A Printer, Cutter or Export component still has result sockets, and you can carry on from them to send a confirmation, archive the file, or update your MIS once the work is really done.

If routing does not behave as expected

What you seeWhat to check
A job stops with no further valid connectionsNo route accepted it. Compare the job's data with your rule, including capitals and stray spaces, and check the value is actually set by that point in the flow.
The same job appears twiceTwo routes both accepted it. Make the conditions mutually exclusive, or remove the route you did not intend.
A branch never runsIts condition is never true, or the previous step leaves by a different socket than you expect. A corrected file leaves Preflight through Fixed, not OK.
A job finishes early with no errorThe socket it used has nothing connected to it, so the route simply ended.
A rule fails on data you know is thereThe value is added later in the flow than this connector, the name is spelled differently, or the value has spaces around it.
A document rule fails on a multi-file jobDocument rules must be true for every file in the job. Test a single property, or split the job earlier.
A script condition reports an errorOpen the log: it names the line number. Guard data the script assumed would be there, and add console.log() lines to see what it received.
You cannot edit the conditionThe flow is running. Stop it, edit, then start it again.
The connector will not drawYou are dropping onto an input component, onto the component you started from, or that socket already connects to that component.

Reference

Rule reference

What you can look at

TypeValueNotes
KeywordAny keyword carried by the job, such as Destination, Approved or DeadlineThe list offers the keywords the flow already knows about, and you can type a name that an earlier component adds at runtime. Names and values are case-sensitive.
DocumentName, Type or SizeType is the file type, such as pdf. Size is in megabytes and takes numeric comparisons only. A document rule must be true for every file in the job.

How you can compare it

ComparisonApplies toTrue when
Is / Is NotText, numbersThe values are equal, or are not. Text comparison is exact, including case and spaces.
Is Less Than / Is Greater ThanNumbersNumeric comparison, rounded to two decimal places.
Is Before / Is AfterDatesChronological comparison. Use a full date and time with an explicit offset, such as 2026-09-30T17:00:00+01:00.
Contains / Does Not ContainTextThe text appears anywhere in the value.
Begins With / Ends WithTextThe value starts or ends with the given text.
Is True / Is FalseYes/no valuesThe value is set that way. No comparison value needed.
Exists / Does Not ExistKeyword, DocumentThe job carries that value at all, whatever it is. No comparison value needed.

Comparisons that do not suit the data are refused when you save. Contains on Document Size is rejected, for example, because a size is a number.

Script reference

A script condition is a single function returning true or false. These objects are available while it runs:

ObjectWhat it holds
KeyThe job's keywords as properties, for example Key.Destination. Use Key.hasOwnProperty('Deadline') to test for presence. Always available, even when the job has no keywords.
DocumentsAn array of the job's files. Each has Name, Type, Size (megabytes), Location, ID, PageCount and Pages; each page has Width, Height and HasShape.
JobThe complete job data as an object, for reading order details that were never turned into keywords.
$The job state written by earlier JavaScript components. An empty object when none has been set.
consoleconsole.log() writes a line to the Workflow log.

Values assigned to Key properties are written back to the job when the script finishes, and changing Key.Copies duplicates job parts, which is why a connector script should test rather than change. An uncaught error, a syntax error or a function that never returns does not simply reject the job: it is reported against the job, with the line number in the message.

Older expression conditions

Conditions built before rules and scripts existed use placeholders in curly brackets. They are still evaluated exactly as before, so a flow that runs well needs no conversion. Rebuild them with Match Rules when you next edit one.

FormMeaning
{Key:Destination} == 'Retail'A keyword substituted into a JavaScript comparison.
{Job:/Job/Order/Priority} == '1'A value read from the job data by path.
{Document:Type} == 'pdf'A document property.
exists {Key:Deadline}True when the keyword is present. !exists inverts it.
{Key?:Deadline}The question mark marks the lookup optional. Without it, a missing keyword makes the job fail rather than quietly rejecting the route.

How a connector is stored

Connectors are saved inside the flow, so copying, duplicating or exporting a flow keeps every route, name and condition with it. In the flow file, one connector looks like this:

<Connector ID="…" Name="Retail">
<From ID="…" Connection="OK"/>
<To ID="…"/>
<Condition>…what is actually evaluated…</Condition>
<Rules>…the rules you built…</Rules>
<Script>…a hand-written script…</Script>
<MatchRules>true</MatchRules>
</Connector>

From carries the socket name, MatchRules records which option is selected, and Condition holds what is evaluated at runtime: either the script generated from your rules, or your own script. A connector whose components are missing, or that repeats a connection that already exists, is dropped when the flow is opened.

Connectors in the API

Flows can also be built and inspected by other systems. Connector conditions are typed there, in four modes: all (accept every job), rules (the rule definition, turned into a script by the server), script and expression (the older placeholder form).

OperationEndpoint
List, read, create, update or delete a connector/flow/{flowId}/connector
Read or replace a condition/flow/{flowId}/connector/{connectorId}/condition
Read or replace the stored XML/flow/{flowId}/connector/{connectorId}/configuration
Read the condition schema/connector/condition/schema
Check a flow before applying it/flow/{flowId}/validate

The same operations are available to AI assistants through the Workflow MCP server. As on the canvas, the flow must be stopped before anything can be changed.


Related: Components and result sockets · Keywords and job data · The JavaScript component · Testing a flow with sample jobs · Job history and problem jobs