The email lands Thursday at 7:52 am, from a customer in Denver. There is a card from the carrier, she writes, asking for $61.84 in import charges before they will hand over her order, and she wants to know if it is a scam. It is not. It is a $78 box of taper candles from your studio in Manchester, and it cleared US customs the way every underdocumented parcel clears customs now: by billing the person least able to fix it.
Two years ago that parcel was invisible. Anything valued under $800 entered the United States duty free under the de minimis rule, which meant the two customs fields on a Shopify product, the HS code and the country of origin, could stay blank for an entire business lifetime without costing a cent. Executive Order 14324, signed July 30, 2025, ended that on August 29, 2025, for every country and every value at once. The response told you how unprepared the world's parcel infrastructure was: in the last week of that August, more than 20 national postal operators, Japan Post announcing on the 25th, Australia Post and Royal Mail stopping on the 26th, much of Europe in the same few days, paused US-bound parcels in whole or in part rather than guess at paperwork they had never been asked for. A temporary flat fee of $80 to $200 per postal package softened the landing for six months; that window closed at the end of February 2026. Then on July 1, 2026, the European Union removed its own 150 euro exemption and replaced it with a flat 3 euro duty counted per product category, and the category is the six digit tariff subheading: a parcel spanning three headings pays three times. Read that twice, because it quietly redefines the field in your admin. The HS code is no longer paperwork that travels with the parcel. It is the unit the bill is counted in.
Your catalog was not built for that. Most catalogs were not. The fields were optional when every product in them was created, no import requires them, no theme displays them, and nothing in the admin has ever chased you about the blanks. The border chases your customer instead.
Two fields nobody filled in
Both fields live on the variant, not the product. The HS code is typically six digits, the part harmonized across countries by the World Customs Organization, and individual countries hang extra digits off the end for their own tariff lines: Shopify's documentation uses 3210.00 as the global code with 3210.00.123 as a UK-specific refinement, and checkout uses the more specific code when one exists. The country of origin is where the product was made or assembled into the thing you sell, not where you ship it from, and the distinction matters because the duty rate is keyed to both fields together.
There are exactly three ways to fill them in. One product at a time on the product page, where typing a description searches for candidate codes. In bulk through the bulk editor, adding the HS code field by hand. Or through a dedicated duties CSV that lives under Settings, then Taxes and duties, which will export your products with missing information, a detail worth knowing because it is the closest thing the platform has to a coverage report, and it only runs when you go get it. Shopify added a store level default for country of origin in May 2025, one value that backfills any variant without its own. For HS codes there is no equivalent: no default, no product level value, no inheritance.
Merchants have started saying this out loud. A June 2026 feature request describes the arithmetic on one product: a hand poured candle in 17 colors is 17 variants, identical in material and origin, and the same code has to be entered 17 times. A reply in July widens the lens: three variants across 400 products is 1,200 fields, most of them the same code, and the reply also explains why a blind product level default would be wrong, because the same bag lands on a different heading in leather than in canvas. Per variant is correct and per variant by hand is unworkable, which is roughly the situation alt text was in before someone let software read the images.
And nothing enforces any of it. A product created tonight publishes without codes, sells without codes, and ships without codes. The one screen that reviews the gap, a step in the duties at checkout setup that flags products with missing information, runs once, during setup, on the catalog you had that day. The products you add next month answer to nobody.
What a blank costs at the border
Shopify does its best with what it has, and what it has degrades in a documented cascade: if a product is missing its HS code, duties at checkout are estimated from the description and the product category instead, and if those are missing too, the calculation still runs and the help center says the result is likely to be inaccurate. The same page carries the sentence that should be printed above every import button: inaccurate product information, such as a missing country of origin or an incorrect HS code, might result in additional duties being charged to the customer upon delivery.
Charged to the customer upon delivery is the polite version of the Denver email. The carrier fronts the duty, adds a brokerage fee, and texts your customer a payment link. Some pay it and quietly resent you. Some refuse the parcel, and it rides back across the ocean at your expense to a returns pile that nobody restocks. Either way the tracking page shows a week of customs limbo first, which is why a customs hold is so often mistaken for a shipment stuck in transit: the package is not lost, it is impounded, and the six digits that would have released it were never in your catalog to print.
Get the code wrong instead of blank and the failure changes direction. A community thread titled Shopify charging 100 percent duties on certain products to the US had collected 20 replies and over 1,200 views by August 2026 and was still active this month: one UK merchant measured duties computed at 95 to 100 percent of the product's price where the correct rate was 3.5 to 5 percent. Nobody checks out through a doubled total, so the error costs you the sale instead of the refund, and no report anywhere will tell you it is happening.
The stories underneath these threads are not edge cases. The merchant who opened the tariff calculation thread two days after de minimis ended ships 70 percent of their business to the US and was running dry run orders to see what checkout would charge. The answer was the wrong method entirely: their postal carrier applies the flat postal tariff, Shopify's calculator assumed a commercial carrier and stacked HS code duties on top, and support's written reply conceded the mismatch, said the team was working to align the calculator with the new postal rules, offered no timeline, and confirmed you are not the only merchant experiencing this. A year later the successor threads, UK sellers on the new tariffs, constant issues with the duty calculator, were still collecting replies. And the fee makes it personal: calculating duties at checkout costs 0.85 percent per order on Shopify Payments, 1.5 percent on other gateways, temporarily lowered to 0.5 percent since February 2025, and it is charged on every order the calculation runs on, including the ones where it ran on blanks.
Six digits of judgment
So the fix is to fill in the fields, and here the problem changes shape, because classification is not data entry. The Harmonized System is a nomenclature of more than five thousand six digit subheadings, revised on a five year cycle, with general rules of interpretation about sets, mixtures, and essential character that customs brokers train on. The difference between two plausible codes is routinely the difference between a single digit duty rate and a double digit one. Guessing low on purpose stopped being a quiet trick, too: replies on the same community threads now warn that customs agencies are penalizing mismatched paperwork, and point to a DOJ and DHS trade fraud task force with whistleblower incentives that reward logistics workers for reporting intentional misclassification. The code has to be right, defensibly, per variant.
Shopify's own tooling concedes the judgment is the hard part. The product page search takes a typed description and suggests codes, one product at a time. Managed Markets assigns codes automatically when you activate it, and the documentation is careful to say the assigned code is not guaranteed to match the one you entered, which is a sentence worth reading as a to-do: somebody should review the differences, and no screen makes that a job.
Here is what makes this tractable in 2026: classifying a product from its title, description, and materials is a reading task, and reading tasks are what language models do. A model that has seen the nomenclature can propose 3406.00 for the taper candle, flag that the ceramic candle holder bundled in the gift set belongs to a different chapter, attach a confidence score and its reasoning to both, and do it four hundred times before lunch. That is the same trick that writes the product descriptions nobody had time for, pointed at a field where the blank has a customs officer at the end of it. What it must not do is publish silently: high confidence proposals batch into the bulk editor with an audit trail, low confidence ones queue for a human, and the genuinely ambiguous handful go to a broker once and come back as a written rule.
What the automation actually has to do
Filling today's blanks is a project. Staying filled is a process, because the catalog keeps moving: new products, new variants, new suppliers, a materials change that quietly invalidates last year's code. The worker this needs watches the catalog and the border rules at the same time. As a Dugong playbook, in plain prose:
# trigger
On every product published or edited,
and every international order
# steps
1. Audit the catalog: HS code, country
of origin, and weight per variant,
coverage counted and kept current
2. Classify with AI: propose six digit
codes from title, description, and
materials, confidence attached
3. Review the tail: high confidence
batches to the bulk editor, low
confidence to a human or a broker
4. Guard the door: a product that goes
live without codes gets flagged the
same hour, not at the border
5. Check the order: international
orders carrying a codeless line item
get held before the label prints
6. Watch the estimates: checkout duty
against carrier invoice, anomalies
flagged as misclassification signals
7. Report monthly: coverage, codes
changed and by whom, duty disputes
and doorstep complaints
Steps one through three are the backfill, and the audit is broader than the codes: Switzerland needs a weight before checkout can price duties at all, so the sweep counts weights and origins too, and reads plausibility while it is there, because a catalog where every product shares one code is usually a catalog where somebody pasted their way out of a warning. Step four is the difference between a project and a process. The platform checks your catalog once, during duties setup; the playbook checks every product the hour it publishes, which is the only moment the fix costs nothing, because no order is carrying it yet.
Step five is the seatbelt, and it is the same reflex as holding the bad address before the label prints: an international order containing a line item with no code is a doorstep bill in progress, and it is cheaper to hold it for an hour than to argue about $61.84 across an ocean. Step six closes the loop nobody closes: checkout collected a duty estimate, the carrier invoiced a real one, and the gap between them is your misclassification report, the place a 100 percent anomaly or a silently absurd rate surfaces before a thread does. When a hold does happen, the customer hears it from you first, with the delay named honestly, not from a carrier's payment link.
Why this is a compiler problem, not an app problem
There are bulk editor apps for HS codes now, and they are fine at what they do, which is move values into fields faster. The judgment is the part that does not fit in their checkboxes: which chapter your gift sets belong to when the candle and the holder disagree, whether your origin is where the wax is poured or where the components came from, which SKUs earn a broker's hour and which can ride a model's 97 percent, what happens to the order that arrives while a code is missing, and who gets told when the EU adds a third identifier in November. Those are sentences about your store, and the argument of the automations no one builds applies verbatim: the sentences should compile into the workflow, instead of being shaved down to whatever a settings page exposes.
Run the Denver order again with the sentences compiled. The gift set publishes Tuesday; within the hour the agent flags it, proposes 3406.00 for the tapers at high confidence, routes the ceramic holder to you with two candidate headings and a recommendation, and you approve both from your phone. Wednesday's order to Denver ships with codes on the customs form, checkout collected $9.12 of duty with the parcel, and the carrier releases it without a text. The email that arrives Thursday at 7:52 am is the customer saying the candles smell like the shop in Manchester she visited in March. Nothing interesting happened at the border, which is the entire point.
The workflow worth building this week
Start with the export the platform already gives you. Go to Settings, then Taxes and duties, then Manage, and export the duties CSV of products with missing information. That file is your blank map. Sort it against last quarter's international orders and the gap stops being abstract: these forty products carried revenue across a border with no code attached.
Fix the top of that list first, by hand or with the classifier proposing and you approving, and set the country of origin default while you are in the settings, because it backfills every blank origin in one save. Then run the watcher in propose-only mode for two weeks: let it classify new products and flag gaps, and check its homework. You are calibrating where its confidence deserves yours, exactly the drill from the pricing guardrail, applied to a slower moving field.
Then say the brief out loud, the way you would hand customs to a new hire. Every variant carries an HS code, an origin, and a weight, and you tell me our coverage number when I ask. Propose codes for anything new the hour it publishes; publish the confident ones with a record of what changed, bring me the doubtful ones, send the truly odd ones to the broker and remember the answer. Hold any international order carrying a blank. Compare what checkout charged with what the carrier billed, and treat a big gap as a wrong code until proven otherwise. Once a month, show me coverage, changes, and every duty complaint. That is the whole paragraph. The compiler turns it into the workflow, and the next card the carrier leaves is for a parcel that is not yours.
If you are a Shopify merchant with a customs story, the
parcel that came back with a bill, the duty calculated at
double the price, the classification you still argue
about, the inbox is open:
field-notes@dugong.live. We are collecting
case studies for the next issue.