{"record":{"id":"8227e86e8c2e26a3","repo":"discordjs/discord.js","slug":"phone-number-must-start-with-a-sign","errorCode":null,"errorMessage":"Phone number must start with a \"+\" sign.","messagePattern":"Phone number must start with a \"\\+\" sign\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/formatters/src/formatters.ts","lineNumber":707,"sourceCode":"\t\tconst searchParams = new URLSearchParams(\n\t\t\tObject.fromEntries(Object.entries(headers).map(([key, value]) => [key.toLowerCase(), value])),\n\t\t);\n\n\t\treturn `<${email}?${searchParams.toString()}>` as const;\n\t}\n\n\treturn `<${email}>` as const;\n}\n\n/**\n * Formats a phone number into a phone number mention.\n *\n * @typeParam PhoneNumber - This is inferred by the supplied phone number\n * @param phoneNumber - The phone number to format. Must start with a `+` sign.\n */\nexport function phoneNumber<PhoneNumber extends `+${string}`>(phoneNumber: PhoneNumber) {\n\tif (!phoneNumber.startsWith('+')) {\n\t\tthrow new Error('Phone number must start with a \"+\" sign.');\n\t}\n\n\treturn `<${phoneNumber}>` as const;\n}\n\n/**\n * The {@link https://discord.com/developers/docs/reference#message-formatting-timestamp-styles | message formatting timestamp styles}\n * supported by Discord.\n */\nexport const TimestampStyles = {\n\t/**\n\t * Short time format, consisting of hours and minutes.\n\t *\n\t * @example `16:20`\n\t */\n\tShortTime: 't',\n\n\t/**","sourceCodeStart":689,"sourceCodeEnd":725,"githubUrl":"https://github.com/discordjs/discord.js/blob/a81ed8a306d37fdc746e26a634b6a42164ba2c8c/packages/formatters/src/formatters.ts#L689-L725","documentation":"`@sapphire/format-util`'s `phoneNumber()` wraps a phone number in angle brackets for mention-style formatting and requires it to start with a `+` (E.164 country-code prefix). Although TypeScript's `+${string}` template type enforces this at compile time, at runtime the function defensively throws a plain Error when the input lacks the leading `+`.","triggerScenarios":"Calling `phoneNumber('15551234567')` with a number missing the leading `+`; passing a value read from user input or a database that stored digits only; JS callers (no type checking) passing any string.","commonSituations":"Phone numbers stored without country code in a database; forms stripping the '+' character; users typing numbers without the international prefix; JavaScript projects bypassing TypeScript typing.","solutions":["Prepend '+' to the number before calling, after normalizing away spaces/dashes/parentheses.","Store and transmit numbers in E.164 format (e.g. +15551234567).","Add a runtime validation/normalization step since JS callers get no compile-time protection.","If the country is known, prepend its dial code (e.g. '+1' for US)."],"exampleFix":"// before\nphoneNumber(rawPhone); // '555-123-4567'\n// after\nconst normalized = '+' + rawPhone.replace(/\\D/g, '');\nphoneNumber(normalized); // '+5551234567'","handlingStrategy":"validation","validationCode":"const toE164 = (raw, defaultCountry = '1') => {\n  const digits = String(raw).replace(/\\D/g, '');\n  if (!digits) throw new Error('Empty phone number');\n  return '+' + digits;\n};","typeGuard":"const isE164 = (s) => typeof s === 'string' && /^\\+\\d{7,15}$/.test(s);","tryCatchPattern":"try {\n  const formatted = phoneNumber(rawPhone);\n} catch (err) {\n  if (err.message.includes('must start with a \"+\"')) {\n    console.error('Phone numbers must be in E.164 format, e.g. +15551234567');\n  } else throw err;\n}","preventionTips":["Store phone numbers in E.164 format at the data layer.","Normalize user input (strip formatting characters, ensure '+') before calling.","Keep the isE164 runtime guard in JS projects where TS types don't apply."],"tags":["sapphire","formatters","phone-number","runtime-validation"],"backgroundTag":"invalid-input-format","analyzedSha":"a81ed8a306d37fdc746e26a634b6a42164ba2c8c","analyzedAt":"2026-08-30T04:07:22.193Z","schemaVersion":2},"datasetVersion":"2026-08-30T08:17:16.595Z"}