NHTSA vPIC often returns forward-collision catalog fields on DecodeVinValues-style payloads -- including ForwardCollisionWarning when the pattern includes that token. Those strings are useful on a free VIN decode card. The trap is turning a single sourced field into an AEB claim, IIHS crash-avoidance grade, or "Collision Prevention Package" that the catalog never asserted.
This post is about honest display: show ForwardCollisionWarning when vPIC provides it, refuse crash-avoidance inventing, and allow a clean "not provided" state when the field is empty. Keep forward-collision catalog values separate from automatic emergency braking marketing, star ratings, and OEM suite names. A sourced token is still only a token: it does not prove the feature is present, calibrated, or undamaged on the listed vehicle. (Lane-departure and blind-spot honesty are separate topics; here the focus is ForwardCollisionWarning.)
What ForwardCollisionWarning is (and is not)
ForwardCollisionWarning is a catalog attribute associated with the VIN decode. It answers a narrow question: which forward-collision warning token did the decode associate with this pattern?
It does not answer:
- Whether the vehicle includes Automatic Emergency Braking (AEB) or pedestrian AEB
- Whether IIHS or NHTSA awarded a crash-avoidance or front-crash-prevention grade
- Camera vs radar hardware, braking intervention, or alert modality you did not source
- Whether the feature works today, was optioned, or was deleted after manufacture
- A composite "collision prevention score" built from missing neighboring fields
Empty ForwardCollisionWarning does not authorize a default "Standard" badge, and a positive token does not mean "AEB verified." Do not fill gaps from Make/Model/Year folklore or a chart keyed only by model year.
Normalize empties, do not invent grades
Treat blank, "Not Applicable", "N/A", and similar tokens as missing. Keep a sourced string when present; do not rewrite it into "AEB Standard" or an IIHS-style crash-avoidance grade.
const EMPTY = new Set([
"",
"not applicable",
"n/a",
"na",
"null",
"none",
"unknown",
]);
export type ForwardCollisionView = {
value: string | null;
source: "vpic" | "missing";
};
export function viewForwardCollisionWarning(fields: {
ForwardCollisionWarning?: string | null;
}): ForwardCollisionView {
const raw = (fields.ForwardCollisionWarning ?? "").trim();
if (!raw || EMPTY.has(raw.toLowerCase())) {
return { value: null, source: "missing" };
}
return { value: raw, source: "vpic" };
}
export function forwardCollisionLines(view: ForwardCollisionView): string[] {
if (view.source === "missing") {
return [
"Forward collision warning: not provided by vPIC for this VIN",
];
}
return [
`Forward collision warning (vPIC): ${view.value}`,
"Catalog token only -- not an AEB or crash-avoidance grade",
];
}
The footnote matters. Buyers over-read a single forward-collision field as verified AEB. Show the sourced token; if blank, say "not provided" -- no greyed "Standard" and no invented braking claim.
Forbidden upgrades
Product pressure often asks for:
- Mapping any non-empty ForwardCollisionWarning into "AEB included"
- Inventing IIHS / Euro NCAP / star-equivalent crash-avoidance language from the catalog field
- Bundling ForwardCollisionWarning with other ADAS keys into "Full Collision Prevention"
- Defaulting blank ForwardCollisionWarning to "Standard" so mid-trim cars look complete
- Renaming catalog tokens into OEM suite marketing names you did not source
Refuse those. If you show other ADAS catalog fields from separate sourced keys, show each on its own row. Never invent AEB or package language inside the ForwardCollisionWarning mapper.
export function assertNoFcwCrashInvent(moduleSource: string): void {
const banned = [
/aeb included/i,
/automatic emergency braking/i,
/iihs/i,
/crash.?avoidance grade/i,
/front crash prevention/i,
/full collision prevention/i,
/euro ncap/i,
];
for (const re of banned) {
if (re.test(moduleSource)) {
throw new Error(
`ForwardCollisionWarning module must not invent crash grades: ${re}`,
);
}
}
}
export type CardRow = { label: string; value: string };
export function cardRows(fields: {
ForwardCollisionWarning?: string | null;
AdaptiveCruiseControl?: string | null;
PedestrianAutomaticEmergencyBraking?: string | null;
}): CardRow[] {
const view = viewForwardCollisionWarning(fields);
const out: CardRow[] = [];
if (view.source === "missing") {
out.push({
label: "Forward collision warning",
value: "not provided",
});
} else {
out.push({
label: "Forward collision warning",
value: String(view.value),
});
}
const acc = (fields.AdaptiveCruiseControl ?? "").trim();
if (acc && !EMPTY.has(acc.toLowerCase())) {
out.push({ label: "Adaptive cruise (vPIC)", value: acc });
}
const paeb = (fields.PedestrianAutomaticEmergencyBraking ?? "").trim();
if (paeb && !EMPTY.has(paeb.toLowerCase())) {
out.push({
label: "Pedestrian AEB catalog (vPIC)",
value: paeb,
});
}
return out;
}
Keep neighboring catalog fields on their own labeled rows. Never concatenate them into "Full Collision Prevention Package," and never treat a separate pedestrian-AEB catalog key as proof that ForwardCollisionWarning implies braking.
UI copy that stays honest
Prefer:
- "Forward collision warning (vPIC): Standard"
- "Forward collision warning: not provided by vPIC for this VIN"
- A short footnote: catalog token, not an AEB or crash-avoidance grade
Avoid:
- "IIHS Front Crash Prevention Superior -- verified"
- "AEB Standard included"
- Grey placeholders that look like real forward-collision data when the field was empty
Quick checks
import assert from "node:assert/strict";
assert.equal(viewForwardCollisionWarning({}).source, "missing");
assert.deepEqual(
forwardCollisionLines(viewForwardCollisionWarning({})),
["Forward collision warning: not provided by vPIC for this VIN"],
);
const std = viewForwardCollisionWarning({
ForwardCollisionWarning: "Standard",
});
assert.equal(std.value, "Standard");
assert.ok(
forwardCollisionLines(std).some((l) =>
/not an AEB or crash-avoidance/i.test(l),
),
);
assert.ok(
!forwardCollisionLines(std).some((l) =>
/iihs|aeb included|collision prevention package/i.test(l),
),
);
const rows = cardRows({
ForwardCollisionWarning: "",
AdaptiveCruiseControl: "Standard",
PedestrianAutomaticEmergencyBraking: "Standard",
});
assert.ok(
rows.some(
(r) =>
r.label.includes("Forward collision") && r.value === "not provided",
),
);
assert.ok(rows.some((r) => r.label.includes("Adaptive cruise")));
assert.ok(rows.some((r) => r.label.includes("Pedestrian AEB")));
assert.ok(!rows.some((r) => /iihs|aeb included/i.test(r.value)));
Review rule: forward-collision modules must not contain AEB-upgrade or crash-avoidance-grade phrases except in forbidding tests. Never upgrade a blank into "Standard."
Takeaway
ForwardCollisionWarning is a catalog token. Display it with clear sourcing, allow "not provided," and never use it as a key into invented AEB claims, IIHS crash-avoidance grades, or "full collision prevention" bundles. Your free VIN UI stays trustworthy when forward-collision data is either a real vPIC value with a modest footnote -- or absent -- and crash-avoidance marketing lives somewhere else, clearly labeled, or not at all.
I maintain VIN Lookup, a free VIN decode based on NHTSA data.
Top comments (0)