B
HomeLibrariesCode AISearchProjectsBookmarksAddress
FeedbackHelp Desk
Libraries
Code LibraryDiagramsAssembliesProductsCalculatorsChecklistsCSI MasterFormat SpecificationsPermitsAddress ReportDOT SpecsModel CodesTransportationRailroadFire SafetyAccessibilityStructuralTransit SpecsUSACE
Other Jurisdictions
Transportation
MUTCDFHWA FP-14
Accessibility
ADA StandardsPROWAG
PricingLog in

Corrections

This is the complete public record of things BuildSpec published that were wrong. Every entry states what was wrong, how it was found, and what changed — including the cases we found ourselves and would rather not have published at all.

A code reference that has never issued a correction is either very young or not looking. We would rather you be able to see our error rate than have to assume it. Entries are never quietly edited to look better; a correction to a correction gets its own entry.

If you find something wrong, email support@buildspec.codes. For how the data gets verified in the first place, see Methodology.

5 corrections, newest first.

Material errorCode library, search and Code AI

31,205 placeholder rows removed from code search, and the section count corrected

What was wrong

The code library held 81,760 rows. 31,205 of them were not code. They carried a section number and an invented title over template text — most commonly "This section establishes specific code requirements. Refer to the official…" — and a single section number could hold dozens of them under different made-up titles. Some were worse than empty: NEC 680.22, which governs receptacle placement near pools and spas, was served with the body "This section covers allowable building height, area, and number of stories". That is building-code text about storeys and floor area attached to an electrical shock-hazard provision. Every one of these rows had an embedding, so every one was reachable by semantic search and by Code AI. The existing de-duplication made this worse rather than better: when several rows shared a section number it kept the longest, and a 268-character placeholder beats the genuine 152-character text of IPC 402.4. Separately, the figure BuildSpec published as "81,760 code sections" was the raw row count. Counting only genuine, distinct sections the real number is 7,613 — the published figure overstated coverage by a factor of 10.7, and it appeared on the home page, the pricing page, the help page, /llms.txt and /methodology.

How it was found

Internally, and by accident. While preparing to publish code tables we read the rows behind IBC Table 1004.5 and found 30 rows for one section carrying 13 different titles. Pulling the same view for NEC 680.22 returned 47 rows with 29 different bodies, at which point the pattern was obvious. The placeholder text had never been sampled because the row count looked healthy — the number that should have prompted the check was the same number that made everything look fine.

What changed

Placeholder rows are excluded from every retrieval path — semantic search, text search and Code AI — by a single shared database predicate, so the rule cannot drift between call sites. Nothing was deleted: the rows remain as the audit trail and as the work list for re-ingestion, exactly as the withdrawn DOT sections were kept. The published section count is now the count of distinct genuine sections, 7,613, derived by the same query that feeds every other figure on the site, and the number of excluded placeholder rows is published on the methodology page rather than quietly netted off. The de-duplication tiebreak that preferred the longest text is now safe, because the placeholders it was preferring are gone from the candidate set.

Scope

31,205 of 81,760 rows. Genuine coverage is 7,613 distinct sections across 15 code editions, 5,656 of them California. Among the genuine rows there are no conflicting texts for the same section — every conflict came from placeholders. Re-ingesting the affected sections from lawfully sourced publications is open work.

Material errorState DOT specifications (/dot-specs)

880 fabricated State DOT specification sections withdrawn

What was wrong

Sixty documents in the DOT corpus were not extractions of real agency publications. They were templated: 20 states x 3 documents x a fixed 18 design / 14 construction / 12 materials section split, 880 sections in total, perfectly uniform. The text read as confident, specific engineering guidance and was wrong in the details that matter. The Caltrans Highway Design Manual page we served at section 2-1 stated a maximum superelevation rate of 10% for rural highways and 6% for urban facilities. Caltrans Topic 202 actually allows 12% on two-lane conventional rural highways and caps urban streets below 35 mph at 4%. A designer following our page would have been under-designed on one and over-designed on the other, on a real safety parameter. The manual also has no section numbered 2-1; it uses Topic and Index numbering.

How it was found

An internal audit of the DOT corpus, not a user report. The uniformity was the tell: no genuine specification book has exactly 18, 14 and 12 sections three times over in twenty states. The filesystem and the database agreed exactly, which ruled out a partial-extraction explanation. The claim was then checked line by line against the published Caltrans manual before anything was deleted, so the withdrawal rests on the content being wrong rather than on the provenance being suspicious.

What changed

All 880 section files and the 60 containing directories were deleted, and fullText was removed for those documents so the site can no longer render a section page for them. Middleware returns 410 Gone across the entire section space of the 60 documents. 410 rather than 404 because these URLs are permanently withdrawn, and because without it the section route would have fallen back to the state's real standard-specifications directory and served unrelated spec text under the old URL — deleting the files alone would have made the problem worse. Document landing pages still return 200 and now link out to the agency's own site instead of claiming full text. The DOT sitemap dropped from 9,063 to 8,182 URLs automatically. The 880 database rows were deliberately kept at verified = false rather than deleted: retrieval already excludes them, and they are the audit trail. A structural guard now runs before ingestion and refuses templated documents outright, and the ingest script writes `verified` explicitly instead of inheriting a column default of true. Re-extraction from the real sources is in progress, Illinois first.

Scope

880 sections, 60 documents, 20 states. 8,213 genuine sections across 47 documents were unaffected. A wave of 410s in Search Console is the intended signal.

Material errorCalculators — Wire Size

NEC conductor ampacity table corrected in the wire-size calculator

What was wrong

Eleven aluminium ampacities in NEC Table 310.16 were wrong — 12 AWG aluminium was shown as 15/15/15 where the table reads 15/20/25, 10 AWG as 24/24/24 where it reads 25/30/35, and so on up the range. 14 AWG aluminium was offered as a choice at all, and no such row exists in 310.16. Two copper values were wrong at 90 degrees C (2/0 shown as 200 where it is 195, 3/0 as 230 where it is 225), and while writing the regression tests a third surfaced: 1 AWG copper at 90 degrees C is 145 A, not 150. The 14, 12 and 10 AWG copper rows were flattened to 15/20/30 across all three temperature columns — those are the 240.4(D) small-conductor overcurrent limits, not ampacities, published under a field labelled 'Ampacity Rating'. That both stated a false number and hid the 90 degrees C value that derating math depends on. 'Breaker Size' was a fixed string per row, shown identically for 60 degrees C aluminium as for 90 degrees C copper. Insulation labels were wrong too: THHN was listed as a 60 degrees C insulation, and it is 90 degrees C. The table also stopped at 4/0, so any feeder above roughly 230 A had no correct answer.

How it was found

An internal correctness audit of all eight calculators, checked row by row against NEC Table 310.16 rather than against the previous version of our own table. Two further errors were then caught by the golden test cases written during the fix, which is the point of writing them.

What changed

Every wrong ampacity was corrected, 14 AWG aluminium removed, and the table extended through 500 kcmil so large feeders are answerable. The 14/12/10 rows now carry true ampacities, with 240.4(D) applied as a separate, explicit small-conductor rule and 240.6(A) used to select the standard overcurrent device — so the output is computed from material and temperature instead of hardcoded per row, and is now labelled 'Max Overcurrent Device' rather than 'Breaker Size'. Insulation temperature labels were corrected. The calculation was extracted out of the React component into lib/calculators/wire-size.ts and locked with hand-worked golden cases that encode the code provision rather than the implementation, including a regression lock on each corrected value. Those suites run in CI on every push.

Scope

Wire-size calculator. Part of a wider calculator audit that also corrected the NEC 220.82 dwelling-load method, a deck-footing unit conversion that under-sized footings by a factor of twelve, an HVAC storey adjustment applied with the wrong sign, and an IBC 722.6 fire-resistance result that was not capped at 60 minutes.

Quality defectFire-resistance assemblies (/assemblies)

IBC Table 721.1 assembly text repaired after a truncating ingest

What was wrong

The ingest of IBC Table 721.1(1), (2) and (3) clipped three fields at three different lengths: 127 component material entries, 108 construction summaries and 139 titles all ended mid-word with an ellipsis. A whole prescriptive paragraph had been written into a field meant to hold a material name. Separately, the ingest concatenated adjacent table cells with nothing between them, producing strings like 'Type X gypsum wallboard5d cooler6" on center' where the source has three distinct columns for membrane, fastener and spacing. None of it was false — it was the code's own text, damaged in transit — but a legend reading a sentence fragment is not a usable reference.

How it was found

Internally, as a follow-on to an audit of the assembly diagram renderer. The rendering audit surfaced the truncation as a side effect: assemblies were failing to hatch because the material classifier could not match a clipped string.

What changed

All 108 construction summaries were restored to the full code text, recovered from the description field, which had never been truncated — so no re-ingest was needed. 61 material entries were shortened to the actual material name, with the prescriptive detail moved to the field where it belongs. A further 37 materials across 48 layers were recovered by cutting at a clause boundary, accepted only when the result passed balanced-parenthesis, length and cut-position guards. 18 layers failed those guards and were left exactly as they were rather than guessed at. All 32 joined table cells were re-separated by inserting a separator only — no character of source text was changed. 139 truncated titles were deliberately left alone: a title ending in an ellipsis reads as intentional display truncation and the full text is one click away. Assemblies rendering with no hatch at all fell from about 100 to 31, and those 31 are legitimately unnamed group headings in the code.

Scope

127 material layers, 108 construction summaries and 32 joined cells across 1,173 assemblies. The generator that produced the data is not itself in the repository, so a future regeneration could reintroduce this — that is tracked as open work.

Quality defectFire-resistance assemblies (/assemblies)

Assembly diagrams rebuilt after eight rendering defects

What was wrong

Eight distinct defects. Joint callout circles were anchored past the right wall's far edge, outside the viewBox, so every one of 72 joint diagrams rendered with its numbers cut off or invisible. On 389 beam and column thumbnails the callout was drawn below the bottom edge of the canvas. Callout circles collided whenever adjacent layers were thin. A substring test matching 'r-' hatched 'air-cooled slag' and 'paper-backed' as insulation; unit masonry was classified as cast concrete; clay brick and structural clay tile had no hatch at all; fire-retardant-treated wood, mass timber, plaster and metal lath fell through to a generic fill across 102 layers. Placeholder rows reading 'None' were drawn as real hatched layers, asserting an element that is not in the assembly. Worst for trust: where a layer's thickness was unknown, the overall dimension label printed the sum of internal fallback values — so a one-layer wall of unknown thickness was labelled 0.75 inches as though it had been measured.

How it was found

Internally, by rendering all 1,173 assemblies at both sizes the application actually uses and inspecting the output, rather than spot-checking a handful. Several defects only appear at thumbnail size, which is why a full-corpus render found them and review had not.

What changed

A shared de-collision routine now spreads callouts along one axis, preserving order and tightening pitch instead of overflowing the canvas. Beam and column members reserve a callout lane and clamp defensively. Joint callouts moved inside the frame. The material classifier checks masonry before concrete, tightened the R-value test to a real pattern, and gained cases for the missing material families. Placeholder layers are filtered out through a single shared function used by the diagram, the legend, the spec table and the layer count, so numbering cannot drift between them. The dimension label now renders only when the thickness is genuinely known — from the data, or from a sum where every layer states its own — and is omitted otherwise. All of this is gated in CI: every assembly renders at both sizes on every push and the check fails on a throw, empty output, NaN in an attribute, or a callout outside the canvas.

Scope

1,173 assemblies. 429 of 4,574 layers still state no thickness, so on those assemblies the drawn layer widths are not evidence of anything — the diagrams are explicitly not to scale.