Skip to main content

diagnosing-number-behaviour

Work out why a specific phone number parses, validates, formats, geocodes or types the way it does, and whether the cause is upstream Google metadata or a bug in this port. Use for any report of the form "number X in region Y returns Z but should return W", for triaging an incoming issue about a number or country code, and before starting a fix on reported number behaviour.

Jump to install

Source facts

Repository
twcclegg/libphonenumber-csharp
Last source activity
September 17, 2026 at 01:20
Detected SKILL.md language
English
Stars
922
Forks
157

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
diagnosing-number-behaviour
description
Work out why a specific phone number parses, validates, formats, geocodes or types the way it does, and whether the cause is upstream Google metadata or a bug in this port. Use for any report of the form "number X in region Y returns Z but should return W", for triaging an incoming issue about a number or country code, and before starting a fix on reported number behaviour.
# Diagnosing a reported number result Most reports of the form "this number is wrong" are **not fixable in this repo**. The library is code plus a verbatim copy of Google's metadata, and the metadata is the answer far more often than the code is. Establish which one you are looking at before writing a fix, or you will edit `resources/` and have it silently reverted by the next sync. ``` Diagnosis: - [ ] 1. Reproduce against the shipped metadata (scratch test) - [ ] 2. Compare with Google's demo for the same number + region - [ ] 3a. Metadata → explain the rule, point upstream, no code change - [ ] 3b. Port bug → read the Java, then follow porting-upstream-changes ``` ## 1. Reproduce against the shipped metadata Add a temporary `[Fact]` named `Scratch` to `csharp/PhoneNumbers.Test/TestPublicApiRobustness.cs` — that class already uses `PhoneNumberUtil.GetInstance()`, i.e. the real embedded metadata, where `TestMetadataTestCase` would give you synthetic regions instead. Run just that fact: ```bash dotnet test csharp/PhoneNumbers.Test --filter "FullyQualifiedName~Scratch" --logger "console;verbosity=detailed" ``` Print the whole picture, not only the failing assertion: `IsValidNumber`, `IsPossibleNumberWithReason`, `GetNumberType`, `GetRegionCodeForNumber`, and `Format` in E164 / INTERNATIONAL / NATIONAL. The distinction between *possible* (length) and *valid* (pattern) explains a large share of reports on its own. Delete the scratch fact once you have the answer, or promote it to a real regression case if this turns out to be a port bug. ## 2. Apply the split **Compare against Google's own demo — <https://libphonenumber.appspot.com> — with the same number and region.** That single comparison is the discriminator: | Google's demo | This library | Verdict | | --- | --- | --- | | Same (wrong) answer | Same (wrong) answer | **Upstream metadata.** Not fixable here. | | Correct answer | Different, wrong answer | **Port bug.** Fix it here. | Also *not* a metadata issue, even though it can look like one: anything about build, packaging, NuGet, trimming/AOT, performance, or API design; and anything about geocoding/locale **display names**, which this repo generates itself from a local JDK via `lib/DumpLocale.java` rather than syncing from Google. The repo automates this same judgement on new issues — `.github/workflows/triage_metadata_issues.yml` classifies them against `.github/triage/system_prompt.md` and the verified history in `.github/triage/metadata_examples.md`. Read those examples when a case is borderline; they are the human-verified record of what has actually turned out to be metadata here. ## 3a. If it is metadata Say so, point the reporter at <https://github.com/google/libphonenumber/issues>, and explain that the next sync (~every two weeks) brings the fix once Google publishes it. **Do not edit `resources/`** — see the `syncing-upstream-metadata` skill. To show *why* the library answers as it does, read the rules rather than guessing: - `resources/PhoneNumberMetadata.xml` — find `<territory id="GB" …>`; the `<generalDesc>`, the per-type descs (`<mobile>`, `<fixedLine>`, …) and `<availableFormats>` under it are the entire basis for validity, type and formatting. - `resources/ShortNumberMetadata.xml` — short codes and emergency numbers. - `resources/geocoding/<lang>/<country-code>.txt`, `resources/carrier/`, `resources/timezones/` — the prefix maps behind the geocoder / carrier / timezone trio. Quoting the exact pattern that rejected the number turns "it's a metadata issue" into an answer the reporter can act on upstream. ## 3b. If it is a port bug Read the Java for the same code path before changing anything, and follow the `porting-upstream-changes` skill. A genuine divergence usually means a ported method drifted, not that the algorithm needs redesigning. Add the number as a regression case where the `writing-tests` skill says real-metadata cases go — a case parked in a `TestMetadataTestCase` class proves nothing about the real number. Check `docs/api-differences-from-java.md` first: some differences from Java (`string` where Java takes `CharSequence`, the library's own `Locale` type) are deliberate, documented, and not bugs.
View on GitHub