Why flow imports fail, and how to fix them
Most failed flow deployments come from a small number of causes. The console's import error is often generic ("The flow is invalid" or InvalidContactFlowException), so it helps to know where to look. The validator checks these before you try the import.
1. The JSON itself is broken
Hand edits, merge conflicts and copy-paste from chat tools leave trailing commas, smart quotes or truncated files. These fail before Connect even reads the flow. The validator reports the exact line and column, so fix those first.
2. References to resources that don't exist in the target
Every queue, prompt, Lambda function, Lex bot, hours of operation and transfer-to-flow reference is stored as a full ARN that includes the instance ID and account ID. Export from Dev and import into Prod, and every one of those ARNs points at Dev. The validator flags ARNs whose account or instance differs from the rest of the flow, and ARNs that are badly formed.
Fix: replace environment-specific ARNs with parameters using the ARN Parameterizer, then substitute the target values at deploy time.
3. Lambda functions not associated with the instance
Even with the correct ARN, an Invoke AWS Lambda function block fails if the function hasn't been added to the instance (Flows → AWS Lambda in the instance settings, or the AssociateLambdaFunction API). The same applies to Lex bots. Make association part of your deployment pipeline, not a manual step.
4. Missing transitions
Blocks that can fail need an Error transition, and input blocks need Timeout and Default paths. A flow with a dangling transition may import but behave unpredictably in production. The validator walks the full graph from the start action and lists unreachable blocks and missing branches.
5. Flow type mismatch
An inbound flow, a customer queue flow, a whisper flow and a module are different types, and some blocks are only valid in certain types. A Transfer to queue block inside a whisper flow, for example, is rejected. Make sure you import into a flow of the same type you exported from.
What the validator checks
Each run gives the flow a readiness score out of 100 and a verdict: Ready to import, Ready, with warnings to review, or Not ready to import. The checks go beyond JSON structure:
- Promotion readiness: ARNs that point to more than one AWS account, region or Connect instance. That usually means a resource from dev was left in a prod flow. Hard-coded ARNs are counted so you can replace them with the ARN Parameterizer.
- Block settings: Lambda timeouts above the 8-second limit, the same keypad option used for two branches, options a keypad can't send, input timeouts of zero, empty prompts and Loop blocks without a count.
- Prompts: SSML that isn't well-formed or uses tags Amazon Polly doesn't support, and
<speak>tags typed into a plain Text prompt, where the caller would hear them read out. - Attributes:
$.Attributesreferences that are never set, including likely typos such ascustmerTiernext tocustomerTier, and attributes that are set but never read. - Flow type: blocks that aren't available in the flow type, such as a queue transfer in a whisper flow. The type is detected automatically, and you can change it.
- Routing and best practice: paths that reach a queue transfer without setting a working queue, loops with no Loop block to limit retries, and missing logging, recording or hours-of-operation checks.
Filter results by severity, mute rules you have deliberately accepted (remembered in your browser), click Show in JSON to select the block in the editor, or Show in diagram to open it in the Flow Visualizer. The Auto-fix tab creates a corrected copy: it connects missing error branches to a block you choose, redirects broken links, removes unreachable blocks and adds a missing Version, and lists every change before you download it.
Worked example: the "Flawed Flow" sample
Load the Flawed Flow sample above and run validation. It is a small five-block flow, but it contains the mistakes we see most often in real exports:
- No start action.
StartActionis empty, so Connect doesn't know which block runs first. Set it to the greeting block (greet). - A Lambda block with no Error branch.
invoke-lambdahas an emptyErrorslist. If the function fails or times out (the block waits at most 8 seconds), the contact has nowhere to go. Add an Error path to the apology prompt or a fallback queue. - A malformed ARN. The Lambda ARN's account segment is
12345, but AWS account IDs are 12 digits. Re-select the function in the designer rather than editing the ARN by hand. - An orphan block.
orphaned-apologyhas no incoming transition, so it can never run. Connect it to the Lambda Error branch from point 2, which fixes both problems at once. - A dangling reference. The menu block
get-inputhas an empty defaultNextAction, sends errors toold-target-block(a block that no longer exists), and has no path for option 2. Point every branch at a real block, and add a Timeout path.
Fix each one in the flow designer, export again, and re-run validation until it is clean before you import.
A safe promotion workflow
- Export the flow from the source environment.
- Validate it here, and fix structural issues in the source environment, not in the JSON.
- Parameterize the ARNs.
- Deploy with CloudFormation (
AWS::Connect::ContactFlow) or theCreateContactFlow/UpdateContactFlowContentAPIs, substituting target ARNs. - Make one test call per branch in the target environment, then check the flow logs.