ASD-US-F is not a tracking number: stop looking up service codes

ASD-US-F is not a tracking number: stop looking up service codes

Some of the strings people paste into a tracking box cannot possibly be tracking numbers, and you can tell before you call anything. We run a free multi-carrier tracker (24hTrack — paste any tracking number, the carrier is detected automatically, no sign-up), so our tracking box takes whatever a shopper happens to be holding. Looking at search demand for one carrier's page this month, a cluster of queries turned out to be people trying to track strings like ASD-US-F and ASD-US-M. Those are not identifiers. They are service codes — they name the shipping product that was purchased. The same string sits on every parcel sent that way. There is nothing to look up, and no carrier API will ever resolve one. Why this reaches your code at all Three fields travel together through a checkout, a WMS, a label API and a notification email: field identifies cardinality service / product code the tariff bought a handful per carrier order reference the order in the shop's DB one per order tracking number one physical parcel one per parcel They get mixed up because all three are short alphanumeric strings that arrive in the same payload, and because a notification template that interpolates the wrong one still renders fine. The bug surfaces later, as "tracking not working", with no stack trace attached. The only safe client-side verdict It is tempting to write a validator that decides what is a tracking number. Don't. Carrier formats collide, change, and contradict their own documentation. What you can decide locally is the narrow negative: this string cannot be an identifier. const DIGITS = /\d/g; export function classifyPastedCode(raw) { const s = String(raw ?? '').trim(); if (!s) return { kind: 'empty' }; // \s already covers NBSP and figure space, which is what PDFs and HTML tables leak in. const compact = s.toUpperCase().replace(/\s/g, ''); const digits = (compact.match(DIGITS) || []).length; const ratio = digits / compact.length; // A service/product code names a TARIFF, not a parcel. if (digits === 0) return { kind: 'service_code', reason: 'no digits at all', value: compact }; if (ratio service_code no digits at all "ePacket" -> service_code no digits at all "Economy Delivery" -> service_code no digits at all "AS123456789US" -> candidate_tracking_number len=13 digits=9 "AS123456789US" -> candidate_tracking_number len=13 digits=9 "1Z999AA10123456784" -> candidate_tracking_number len=18 digits=15 "ZHPHD260713551753ML" -> candidate_tracking_number len=19 digits=12 "9400150206217912" -> candidate_tracking_number len=16 digits=16 "ORD-77421" -> candidate_tracking_number len=9 digits=5 "AB-12" -> too_short Enter fullscreen mode Exit fullscreen mode Two lines deserve attention. ORD-77421 is a shop order reference and it passes through as a candidate — deliberately. Some carriers do accept a sender reference as a lookup key, sometimes paired with a postcode. A client-side rule that rejected it would break a working path to save a round trip. The classifier's job is to stop the impossible, not to pre-empt the carrier. The non-breaking-space line matters more than it looks. Numbers copied out of a PDF or an HTML table arrive full of them, and a plain /\s/ already strips them — that one is free. What it does not strip is a zero-width space, because U+200B is not whitespace at all; it is a format character. If you want those gone too, /\p{Cf}/u catches them, and that is the invisible character most likely to make a perfectly correct-looking number fail a strict regex. Four things worth changing 1. Store the service code in its own column. If it lands in tracking_number, every downstream consumer inherits a value that can never resolve, and you cannot tell those rows apart from genuine not-founds. 2. Separate "no number yet" from "number not found". They look identical in a UI that only has a spinner, and they need opposite responses: wait, versus go back to the sender. Most of the "your tracking is broken" reports we see are the first one. 3. Never resolve a guess into a concrete carrier silently. Store an unresolved state instead. A guessed carrier is indistinguishable from a confirmed one once it is written, and the first carrier response that actually finds the number can settle it properly. 4. Echo the input back when you reject it. The person still has the label in front of them. Could not read "ASD-US-F" as a tracking number — that looks like a service name. The parcel number is usually longer and mostly digits. is a message someone can act on; Invalid tracking number is not. Why it keeps happening The parcel usually has two companies on it. One gets it out of the origin country, another delivers it — and each has its own numbering, its own service names, and its own vocabulary in the scan text. The handover is where a single carrier string and a single tracking_number string stop being enough to describe what happened. Modelling custody as a sequence rather than a field is a bigger change than this classifier, but the classifier is the cheap half, and it removes a whole class of support ticket on day one. Short FAQ Is a service code ever trackable? No. It describes a product, not a parcel, so it has nothing to resolve to. How do I know the real number then? For the carrier in the example above it is 13 characters, mostly digits, typically starting AS and ending US. In general: mostly digits, usually 10-22 characters. If all you have is a service name, the sender still has the parcel number. Should I validate check digits? Where a carrier publishes one, yes — it is the only client-side check that is genuinely conclusive. Just don't extend it by analogy to carriers that don't document one. What about an unrecognised format? Try the lookup anyway, and keep the answer. "Carrier says not found" is real information; "my regex didn't match" is not. Written by the team at 24hTrack, a free multi-carrier tracking site. The search-demand observation comes from our own platform; the classifier is the one in our notes, run as shown before publishing.

Original Source

Read the full article at Dev →

KhanList aggregates and links to publicly available news content. We do not host full articles from third-party sources. Always verify important information with original sources.