Skip to content

Phone field prepends a duplicate "+91 +91" prefix, causing "Invalid Phone Number" on save #244

Description

@harshtandiya

Summary

Phone number fields default to a doubled dial-code prefix (+91 +91xxxxxxxx). Because of the duplicated +91, saving a Talk Proposal (and any other form using the phone input) fails with an "Invalid Phone Number" validation error, forcing users to manually clean up the value on every edit.

Reported in the community chat with a screenshot of the error:

The phone number fields by default have +91 +91xxxxxxxx. Due to having +91 twice it says incorrect phone number every time I edit a talk proposal record and save. Not good experience, extra clicks and cleaning up.

Root cause

The bug is in the frontend phone input, not the doctype (the phone field on Talk Proposal has no default value in talk_proposal.json).

In dashboard/src/components/PhoneInput.vue:

  1. The dial code is hardcoded to India:
    const dialCode = ref("+91"); // line ~40
  2. emitValue() always re-concatenates the dial code onto the number:
    emit("update:modelValue", `${dialCode.value} ${localNumber.value}`); // line ~92
  3. parsePhone() does not cleanly strip an existing dial code from the incoming value:
    const match = value.match(/^(\+\d{1,4})[\s-]?(.*)$/); // line ~72
    The regex is greedy on \d{1,4} and only strips a single separator. When a stored value already contains a dial code (e.g. +91 ...), the leftover +91 ends up inside localNumber, and emitValue() then prepends +91 again, producing "+91 +91 ...".

The malformed value is then rejected by the backend in buzz/api/__init__.py (validate_custom_fields, ~lines 320-325), which calls frappe.utils.validate_phone_number_with_country_code(...).

Suggested fix

  • Make parsePhone() reliably separate the dial code from the local number (match against the known dial-code list from buzz.api.forms.get_dial_codes rather than a greedy regex), and ensure emitValue() never double-prepends when the number already carries a code.
  • Add a regression test for round-tripping a value that already contains a dial code.

Related note (US-first product)

The default dial code is currently +91. Since new business is US-only, the default should be +1. Happy to fold this into the fix or track separately.

Affected files

  • dashboard/src/components/PhoneInput.vue (dial-code default + parse/emit logic — primary)
  • dashboard/src/components/CustomFieldInput.vue (wires PhoneInput for Phone custom fields)
  • dashboard/src/components/ProposalEditDialog.vue (edits Talk Proposal phone via a raw FormControl type="tel", persists the string as-is)
  • buzz/api/__init__.py (validate_custom_fields phone validation)
  • buzz/api/forms.py (get_dial_codes)

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    Status
    Done

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions