FAILURE MAP
← Case archive

FA-96521 / Phone number formatting / Open access

Dial string from E.164: numbers without the plus lose their first digit · case 01

"4255501..." is read as code 2... and the dial string is wrong.

Verified by executionVariant 1 · 9 checks per implementationDownload source bundle ↓JSON ↗

ROOT CAUSE

The leading plus is not required, but the first character is still skipped.

VERIFIED REPAIR

Reject input that does not start with "+".

Unsuccessful approach: Stripping an optional plus accepts national-looking digits as if they were canonical.

Case contract

Input [canonical +digits, caller country]. Toy table (code, exit prefix, trunk): DD 8/00/-, AA 42/00/0, BB 83/810/8, CC 891/011/-. The input must be "+" and digits only. The destination is the longest matching code. Same code as the caller: dial trunk + national number. Otherwise dial the caller exit prefix + code + national number. Unknown caller or code returns None.

Why this case matters

Click-to-call and PBX integrations dial the string produced here; a wrong prefix connects to a different subscriber or fails.

1 / The failure

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(x):
    e164, frm = x
    TABLE = {'DD': ('8', '00', ''), 'AA': ('42', '00', '0'), 'BB': ('83', '810', '8'), 'CC': ('891', '011', '')}
    if frm not in TABLE or not e164[1:].isdigit():
        return None
    digits = e164[1:]
    cc = max((v[0] for v in TABLE.values() if digits.startswith(v[0])), key=len, default=None)
    if cc is None:
        return None
    nsn = digits[len(cc):]
    own_cc, exit_prefix, trunk = TABLE[frm]
    if cc == own_cc:
        return trunk + nsn
    return exit_prefix + cc + nsn
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['domestic call adds trunk', ['+42555011123', 'AA'], '0555011123'], ['domestic call without trunk', ['+8915550135', 'CC'], '5550135'], ['caller code is a prefix of destination code', ['+835550121221', 'DD'], '00835550121221'], ['destination code is a prefix of caller code', ['+8555010141', 'BB'], '8108555010141'], ['three-digit exit prefix', ['+8915550135', 'AA'], '008915550135'], ['spaced E.164 rejected', ['+42 555011123', 'AA'], None], ['missing plus rejected', ['42555011123', 'AA'], None], ['leading zero instead of plus rejected', ['042555011123', 'AA'], None], ['unknown caller country', ['+42555011123', 'ZZ'], None]], [['domestic call adds trunk', ['+42555012234', 'AA'], '0555012234'], ['domestic call without trunk', ['+8915550246', 'CC'], '5550246'], ['caller code is a prefix of destination code', ['+835550122332', 'DD'], '00835550122332'], ['destination code is a prefix of caller code', ['+8555010252', 'BB'], '8108555010252'], ['three-digit exit prefix', ['+8915550246', 'AA'], '008915550246'], ['spaced E.164 rejected', ['+42 555012234', 'AA'], None], ['missing plus rejected', ['42555012234', 'AA'], None], ['leading zero instead of plus rejected', ['042555012234', 'AA'], None], ['unknown caller country', ['+42555012234', 'ZZ'], None]], [['domestic call adds trunk', ['+42555013345', 'AA'], '0555013345'], ['domestic call without trunk', ['+8915550357', 'CC'], '5550357'], ['caller code is a prefix of destination code', ['+835550123443', 'DD'], '00835550123443'], ['destination code is a prefix of caller code', ['+8555010363', 'BB'], '8108555010363'], ['three-digit exit prefix', ['+8915550357', 'AA'], '008915550357'], ['spaced E.164 rejected', ['+42 555013345', 'AA'], None], ['missing plus rejected', ['42555013345', 'AA'], None], ['leading zero instead of plus rejected', ['042555013345', 'AA'], None], ['unknown caller country', ['+42555013345', 'ZZ'], None]], [['domestic call adds trunk', ['+42555014456', 'AA'], '0555014456'], ['domestic call without trunk', ['+8915550468', 'CC'], '5550468'], ['caller code is a prefix of destination code', ['+835550124554', 'DD'], '00835550124554'], ['destination code is a prefix of caller code', ['+8555010474', 'BB'], '8108555010474'], ['three-digit exit prefix', ['+8915550468', 'AA'], '008915550468'], ['spaced E.164 rejected', ['+42 555014456', 'AA'], None], ['missing plus rejected', ['42555014456', 'AA'], None], ['leading zero instead of plus rejected', ['042555014456', 'AA'], None], ['unknown caller country', ['+42555014456', 'ZZ'], None]], [['domestic call adds trunk', ['+42555015567', 'AA'], '0555015567'], ['domestic call without trunk', ['+8915550579', 'CC'], '5550579'], ['caller code is a prefix of destination code', ['+835550125665', 'DD'], '00835550125665'], ['destination code is a prefix of caller code', ['+8555010585', 'BB'], '8108555010585'], ['three-digit exit prefix', ['+8915550579', 'AA'], '008915550579'], ['spaced E.164 rejected', ['+42 555015567', 'AA'], None], ['missing plus rejected', ['42555015567', 'AA'], None], ['leading zero instead of plus rejected', ['042555015567', 'AA'], None], ['unknown caller country', ['+42555015567', 'ZZ'], None]]]
for label, arg, expected in fixtures[N - 1]:
    check(label, solve(arg), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
Boundary fixtureActualExpectedOutcome
domestic call adds trunk05550111230555011123Passed
domestic call without trunk55501355550135Passed
caller code is a prefix of destination code0083555012122100835550121221Passed
destination code is a prefix of caller code81085550101418108555010141Passed
three-digit exit prefix008915550135008915550135Passed
spaced E.164 rejectedNoneNonePassed
missing plus rejectedNoneNonePassed
leading zero instead of plus rejected0555011123NoneFailed
unknown caller countryNoneNonePassed

SHA-256 / bfef1f86252ef617b3d1f686fad865b9369a7ac472ca382b88bed2f3f20a88e6

2 / The unsuccessful fix

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(x):
    e164, frm = x
    TABLE = {'DD': ('8', '00', ''), 'AA': ('42', '00', '0'), 'BB': ('83', '810', '8'), 'CC': ('891', '011', '')}
    if frm not in TABLE or not e164[1:].isdigit():
        return None
    digits = e164.lstrip('+')
    cc = max((v[0] for v in TABLE.values() if digits.startswith(v[0])), key=len, default=None)
    if cc is None:
        return None
    nsn = digits[len(cc):]
    own_cc, exit_prefix, trunk = TABLE[frm]
    if cc == own_cc:
        return trunk + nsn
    return exit_prefix + cc + nsn
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['domestic call adds trunk', ['+42555011123', 'AA'], '0555011123'], ['domestic call without trunk', ['+8915550135', 'CC'], '5550135'], ['caller code is a prefix of destination code', ['+835550121221', 'DD'], '00835550121221'], ['destination code is a prefix of caller code', ['+8555010141', 'BB'], '8108555010141'], ['three-digit exit prefix', ['+8915550135', 'AA'], '008915550135'], ['spaced E.164 rejected', ['+42 555011123', 'AA'], None], ['missing plus rejected', ['42555011123', 'AA'], None], ['leading zero instead of plus rejected', ['042555011123', 'AA'], None], ['unknown caller country', ['+42555011123', 'ZZ'], None]], [['domestic call adds trunk', ['+42555012234', 'AA'], '0555012234'], ['domestic call without trunk', ['+8915550246', 'CC'], '5550246'], ['caller code is a prefix of destination code', ['+835550122332', 'DD'], '00835550122332'], ['destination code is a prefix of caller code', ['+8555010252', 'BB'], '8108555010252'], ['three-digit exit prefix', ['+8915550246', 'AA'], '008915550246'], ['spaced E.164 rejected', ['+42 555012234', 'AA'], None], ['missing plus rejected', ['42555012234', 'AA'], None], ['leading zero instead of plus rejected', ['042555012234', 'AA'], None], ['unknown caller country', ['+42555012234', 'ZZ'], None]], [['domestic call adds trunk', ['+42555013345', 'AA'], '0555013345'], ['domestic call without trunk', ['+8915550357', 'CC'], '5550357'], ['caller code is a prefix of destination code', ['+835550123443', 'DD'], '00835550123443'], ['destination code is a prefix of caller code', ['+8555010363', 'BB'], '8108555010363'], ['three-digit exit prefix', ['+8915550357', 'AA'], '008915550357'], ['spaced E.164 rejected', ['+42 555013345', 'AA'], None], ['missing plus rejected', ['42555013345', 'AA'], None], ['leading zero instead of plus rejected', ['042555013345', 'AA'], None], ['unknown caller country', ['+42555013345', 'ZZ'], None]], [['domestic call adds trunk', ['+42555014456', 'AA'], '0555014456'], ['domestic call without trunk', ['+8915550468', 'CC'], '5550468'], ['caller code is a prefix of destination code', ['+835550124554', 'DD'], '00835550124554'], ['destination code is a prefix of caller code', ['+8555010474', 'BB'], '8108555010474'], ['three-digit exit prefix', ['+8915550468', 'AA'], '008915550468'], ['spaced E.164 rejected', ['+42 555014456', 'AA'], None], ['missing plus rejected', ['42555014456', 'AA'], None], ['leading zero instead of plus rejected', ['042555014456', 'AA'], None], ['unknown caller country', ['+42555014456', 'ZZ'], None]], [['domestic call adds trunk', ['+42555015567', 'AA'], '0555015567'], ['domestic call without trunk', ['+8915550579', 'CC'], '5550579'], ['caller code is a prefix of destination code', ['+835550125665', 'DD'], '00835550125665'], ['destination code is a prefix of caller code', ['+8555010585', 'BB'], '8108555010585'], ['three-digit exit prefix', ['+8915550579', 'AA'], '008915550579'], ['spaced E.164 rejected', ['+42 555015567', 'AA'], None], ['missing plus rejected', ['42555015567', 'AA'], None], ['leading zero instead of plus rejected', ['042555015567', 'AA'], None], ['unknown caller country', ['+42555015567', 'ZZ'], None]]]
for label, arg, expected in fixtures[N - 1]:
    check(label, solve(arg), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
Boundary fixtureActualExpectedOutcome
domestic call adds trunk05550111230555011123Passed
domestic call without trunk55501355550135Passed
caller code is a prefix of destination code0083555012122100835550121221Passed
destination code is a prefix of caller code81085550101418108555010141Passed
three-digit exit prefix008915550135008915550135Passed
spaced E.164 rejectedNoneNonePassed
missing plus rejected0555011123NoneFailed
leading zero instead of plus rejectedNoneNonePassed
unknown caller countryNoneNonePassed

SHA-256 / ef95a7c1f9733700731ca39afadc9bbc8af86736e095421243bbdc3130f779da

3 / The verified repair

Exit 0
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(x):
    e164, frm = x
    TABLE = {'DD': ('8', '00', ''), 'AA': ('42', '00', '0'), 'BB': ('83', '810', '8'), 'CC': ('891', '011', '')}
    if frm not in TABLE or not e164.startswith('+') or not e164[1:].isdigit():
        return None
    digits = e164[1:]
    cc = max((v[0] for v in TABLE.values() if digits.startswith(v[0])), key=len, default=None)
    if cc is None:
        return None
    nsn = digits[len(cc):]
    own_cc, exit_prefix, trunk = TABLE[frm]
    if cc == own_cc:
        return trunk + nsn
    return exit_prefix + cc + nsn
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['domestic call adds trunk', ['+42555011123', 'AA'], '0555011123'], ['domestic call without trunk', ['+8915550135', 'CC'], '5550135'], ['caller code is a prefix of destination code', ['+835550121221', 'DD'], '00835550121221'], ['destination code is a prefix of caller code', ['+8555010141', 'BB'], '8108555010141'], ['three-digit exit prefix', ['+8915550135', 'AA'], '008915550135'], ['spaced E.164 rejected', ['+42 555011123', 'AA'], None], ['missing plus rejected', ['42555011123', 'AA'], None], ['leading zero instead of plus rejected', ['042555011123', 'AA'], None], ['unknown caller country', ['+42555011123', 'ZZ'], None]], [['domestic call adds trunk', ['+42555012234', 'AA'], '0555012234'], ['domestic call without trunk', ['+8915550246', 'CC'], '5550246'], ['caller code is a prefix of destination code', ['+835550122332', 'DD'], '00835550122332'], ['destination code is a prefix of caller code', ['+8555010252', 'BB'], '8108555010252'], ['three-digit exit prefix', ['+8915550246', 'AA'], '008915550246'], ['spaced E.164 rejected', ['+42 555012234', 'AA'], None], ['missing plus rejected', ['42555012234', 'AA'], None], ['leading zero instead of plus rejected', ['042555012234', 'AA'], None], ['unknown caller country', ['+42555012234', 'ZZ'], None]], [['domestic call adds trunk', ['+42555013345', 'AA'], '0555013345'], ['domestic call without trunk', ['+8915550357', 'CC'], '5550357'], ['caller code is a prefix of destination code', ['+835550123443', 'DD'], '00835550123443'], ['destination code is a prefix of caller code', ['+8555010363', 'BB'], '8108555010363'], ['three-digit exit prefix', ['+8915550357', 'AA'], '008915550357'], ['spaced E.164 rejected', ['+42 555013345', 'AA'], None], ['missing plus rejected', ['42555013345', 'AA'], None], ['leading zero instead of plus rejected', ['042555013345', 'AA'], None], ['unknown caller country', ['+42555013345', 'ZZ'], None]], [['domestic call adds trunk', ['+42555014456', 'AA'], '0555014456'], ['domestic call without trunk', ['+8915550468', 'CC'], '5550468'], ['caller code is a prefix of destination code', ['+835550124554', 'DD'], '00835550124554'], ['destination code is a prefix of caller code', ['+8555010474', 'BB'], '8108555010474'], ['three-digit exit prefix', ['+8915550468', 'AA'], '008915550468'], ['spaced E.164 rejected', ['+42 555014456', 'AA'], None], ['missing plus rejected', ['42555014456', 'AA'], None], ['leading zero instead of plus rejected', ['042555014456', 'AA'], None], ['unknown caller country', ['+42555014456', 'ZZ'], None]], [['domestic call adds trunk', ['+42555015567', 'AA'], '0555015567'], ['domestic call without trunk', ['+8915550579', 'CC'], '5550579'], ['caller code is a prefix of destination code', ['+835550125665', 'DD'], '00835550125665'], ['destination code is a prefix of caller code', ['+8555010585', 'BB'], '8108555010585'], ['three-digit exit prefix', ['+8915550579', 'AA'], '008915550579'], ['spaced E.164 rejected', ['+42 555015567', 'AA'], None], ['missing plus rejected', ['42555015567', 'AA'], None], ['leading zero instead of plus rejected', ['042555015567', 'AA'], None], ['unknown caller country', ['+42555015567', 'ZZ'], None]]]
for label, arg, expected in fixtures[N - 1]:
    check(label, solve(arg), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
Boundary fixtureActualExpectedOutcome
domestic call adds trunk05550111230555011123Passed
domestic call without trunk55501355550135Passed
caller code is a prefix of destination code0083555012122100835550121221Passed
destination code is a prefix of caller code81085550101418108555010141Passed
three-digit exit prefix008915550135008915550135Passed
spaced E.164 rejectedNoneNonePassed
missing plus rejectedNoneNonePassed
leading zero instead of plus rejectedNoneNonePassed
unknown caller countryNoneNonePassed

SHA-256 / e0302895b52b670e5ecd1f53486371d5d15a0821adaf64264b871480d1dfb506

Verification & scope

A deterministic toy contract over synthetic, obviously fictitious telephone numbers and toy country tables. The rules are stipulated for this model only and make no claim of conformance with any numbering plan or telecommunications standard. This reproducer isolates one failure mechanism. Results cover the supplied fixtures. Variants within a family share a test contract and should remain grouped when constructing evaluation splits. Related mechanisms with a shared evaluation_group must also remain together; these controlled models are not independent production incidents.

Observations recorded using Python 3.12.14 at 2026-09-29T14:52:23.488569+00:00.

Case digest / dd2ad4f9ca0fa8c8680da7ed761b3fa76868231d6af0ad6fb00368a44288a906