Architect expression fails to format +1XXXXXXXXXX to (XXX) XXX-XXXX

Trying to clean up incoming caller ID data in Architect. The source system passes E.164 format like “+14155552671”. Need it formatted as “(415) 555-2671” for display on the agent desktop.

Tried using the standard string manipulation functions. The expression looks like this:

format("(%s) %s-%s", right(substring(caller_id, 2, 3), 3), right(substring(caller_id, 5, 3), 3), right(substring(caller_id, 8, 4), 4))

Wait, that syntax is wrong for Architect. Actually tried:

concat("(", substring(caller_id, 2, 3), ") ", substring(caller_id, 5, 3), "-", substring(caller_id, 8, 4))

Getting a “Expression evaluation error” in the debug log. The variable caller_id definitely contains the string. Checked the data type, it’s a string.

Also tried using replace to strip the plus sign first:

replace(caller_id, "+", "")

Then applying the substring logic. Still fails. The error message just says “Invalid expression” without pointing to the specific token.

Is there a built-in function for phone number formatting? Don’t want to write a complex regex if there’s a simpler way. The format function in Architect seems limited compared to standard programming languages. Can’t find docs on supported format specifiers.

Also tried this approach:

left(substring(caller_id, 2), 3) 

To get the area code. Works in isolation. But chaining it with concat breaks.

Any ideas on the correct syntax? Or is there a better way to handle this in the flow before the IVR starts? The data comes from the SIP header, so it’s raw.

The nested right calls are unnecessary and likely breaking the parser because the indices are off. substring in Genesys Architect is zero-indexed. If you strip the + and country code, you’re left with 10 digits. You just need to grab chunks of 3, 3, and 4.

Your current logic tries to substring from index 2, then take the right 3 chars. That’s overcomplicated and ne to off-by-one errors if the input length varies. Just use substring directly with the correct start and length parameters.

Try this cleaner expression:

format("(%s) %s-%s", 
 substring(caller_id, 2, 3), 
 substring(caller_id, 5, 3), 
 substring(caller_id, 8, 4)
)

Wait, check the source data first. If caller_id is coming in as +14155552671:

  • Index 0: +
  • Index 1: 1
  • Index 2-4: 415 (Area code)
  • Index 5-7: 555 (Prefix)
  • Index 8-11: 2671 (Line number)

So substring(caller_id, 2, 3) gets 415. substring(caller_id, 5, 3) gets 555. substring(caller_id, 8, 4) gets 2671.

If the input might have variable length or missing country codes, you’ll need a conditional check first to ensure the string length is at least 12 chars before parsing. Otherwise, you’ll get empty strings or errors.

Also, make sure the variable type is set to String in the Data Action output if you’re pulling this from an external API. Sometimes Architect treats it as a number, which strips leading zeros or formats it weirdly.

I ran into this exact issue last week with a hybrid platform setup. The external CTI adapter was sending the number as an integer, so Architect dropped the leading zero on the area code in some regions. Cast it to string first if you’re unsure:

format("(%s) %s-%s", 
 substring(to_string(caller_id), 2, 3), 
 substring(to_string(caller_id), 5, 3), 
 substring(to_string(caller_id), 8, 4)
)

Test it in the expression tester first. It’s easier to debug there than in the flow.