A lot code has exactly one job, and it is not the job most people design it for. It is not there to look organized on a harvest sheet, and it is not there to satisfy an auditor standing in front of you this afternoon. It is there for the day, a year from now, when someone who has never met you receives a code on a complaint form and has to figure out what it means with no one available to ask.
That stranger is the actual audience for a lot code. Not you, next week, when the field is still fresh in your head. Not your crew, who will remember which morning they picked the north block even if the sheet is smudged. The code has to survive the case where every person who could explain it by memory is unavailable — on vacation, changed jobs, or three seasons removed from remembering one Tuesday among two hundred.
Designed for that reader, a lot code turns out to be a small, boring decision, and most of the ways it goes wrong come from making it more interesting than it needs to be. Farms that struggle with it are rarely lacking discipline; they are solving the wrong problem, treating the code as an internal shorthand for this week’s crew rather than as a durable label that has to keep meaning the same thing after everyone who wrote it has moved on.
The code has to decode without a phone call
Test any code you are considering with one question: if this string arrived on a complaint form with no other context, could someone in your operation — not necessarily the person who wrote it — say what field it came from and when it was picked? If the answer requires calling the crew lead, the code has failed its one job, even if every harvest was recorded faithfully elsewhere.
This is a narrower requirement than it sounds. It does not ask for a code that is self-explanatory to a stranger outside your operation — that is what the records the code points to are for. It asks that the code be decodable, by someone inside your operation, from the string alone, without reconstructing it from memory or a separate lookup table that might not survive a staff change.
Notice what this rules out. A sequential number stamped from a hand counter — lot 4,412 — decodes to nothing on its own; it requires a separate ledger mapping numbers to fields and dates, and that ledger is exactly the kind of side document that gets lost, left in a truck that gets sold, or simply never backed up. A code has passed the test only if the string itself, on the day it is read a year from now, still carries its own meaning without a second document to translate it.
This is also why a code should never depend on external context to stay unique — a numbering scheme that resets each January collides the moment last year’s records and this year’s sit in the same spreadsheet without a year prefix. Build the year, or at minimum the full date, into the string itself.
Encode origin, not everything
The useful shape is crop, field or block, and date — three facts that are fixed at the moment of harvest and never change afterward. A code like TOM-northfield-0714 tells a reader the crop, the field, and the day, and nothing about it depends on what happens to the lot next.
If one field carries two varieties — early and late lettuce in the same block, say — add the variety, because variety is also fixed at harvest and a recall on one variety should not implicate the other. The test for whether a fact belongs in the code is whether it is already true and unchangeable at the moment the bin fills. If it is, it earns a place. If it depends on a decision made later — which customer, which truck, which pack line — it does not, no matter how convenient it would be to have it on hand.
Resist the urge to fold in more. A code that also encodes the customer cannot survive a lot being split across three buyers. A code that encodes the pack date rather than the harvest date describes the wrong event — see pack date versus harvest date for why the two answer different questions in an investigation. The lot code’s job is to name where and when the product came into existence. Everything downstream — who bought it, when it shipped, what it was packed into — belongs in the records that reference the code, not in the code itself.
Assign it at harvest, not at the loading dock
A code is only as useful as the moment it is born. Assigned at harvest, it carries the field and the date forward automatically, because at that moment those facts are still attached to the product. Assigned later — at wash, at pack, at the loading dock — it can only describe what left the building that day, because by then the product from several fields or several mornings may already be mixed, and the code cannot un-mix what commingling has already joined. That failure mode is common enough to deserve its own page: see commingling and lot integrity.
The practical rule: the code goes on the harvest sheet, in the field or at the truck, written by the person doing the picking, at the same moment the bin fills. Anyone who assigns codes later is reconstructing, and a reconstructed code is a guess wearing the authority of a record.
A repeatable structure beats a memorable one
The two failure modes are opposites, and both are common. A code too simple — a sequential number, a date alone — will eventually repeat by coincidence, and a code that resolves to two different plantings implicates both when only one was involved. A code too elaborate — one that tries to encode variety, crew, irrigation zone, and pick number all at once — becomes something nobody fills in correctly under pressure, and an incorrectly filled-in code is worse than a simple one, because it carries false confidence.
Aim for the smallest structure that cannot repeat: crop plus field plus date is usually enough, because a field is not harvested twice on the same day under normal operation. Add a sequence letter only for the case where it genuinely can — two picks of the same block in one day, say, distinguished as -A and -B.
The code is worthless until it is carried forward
None of the design above matters if the code stops at the harvest sheet. A lot code earns its keep only by appearing again — on the pack record, on the sales invoice, on the customer’s receipt — spelled identically every time. This is the discipline covered in recording shipments and customers, and it is worth stating plainly here: a well-designed code that gets re-typed loosely from memory at the sales desk fails in exactly the way a badly designed code does. Design and discipline are two different problems, and both have to be solved.
For the wider argument about why this matters at all — what a trace is actually for, and what it takes to run one under a deadline — see the traceability guide, or the full traceability cluster.
Where a joined record removes the retyping
The reason a well-designed code still fails in practice is almost never the design. It is the second and third time it has to be typed by hand — once on the pack sheet, again on the invoice — each retyping a chance for a transposed digit that silently breaks the join. Farm40 records input applications, harvest lots, and customer sales as first-class, linked fields, so a lot code entered once at harvest is selected, not retyped, on every later record that touches it. The limit is the same one that applies to any joined system: the link is a lot-code string match, so a sale entered with a blank or mistyped code will not connect to its lot, and the software cannot detect a code that was never entered in the first place. It removes the retyping. It does not remove the discipline of writing the code down at all.
