← back to Sample Followup Sweep
sample-followup: strip CR/whitespace from FileMaker vid — it was silently dropping chases (TK-11255)
e343b5f7af18ff8cf72ff06bc0cc740763b4cbb3 · 2026-09-12 07:41:39 -0700 · Steve Abrams
Measured live against FileMaker, not hypothesised: of 129 overdue sample records
in the current 10-60 day window, 11 across 7 vendor codes resolve to NO contact
and are skipped with no error and no log line. One of those is a plain key bug.
A Kravet record's vid is literally "kra\r". scheduled-run.mjs keyed the contact
map with String(vid).toUpperCase() and no trim, so "KRA\r" never matched "KRA"
and that vendor's overdue sample was never chased. Same untrimmed pattern in
resolve-original-dates.mjs. build-fleet.js already strips \r from Mfr Pattern and
client name — vid was simply missed.
This is the silent-skip class: nothing errors, nothing logs, the sample just
never gets chased and a client waits.
Both sites now strip CR/LF and trim before upper-casing.
The other 6 skipped vids are NOT this bug and are deliberately not touched here:
1838, FUT, VAH, BRU -- vid absent from data/fleet.json, which is 29 days stale
and is regenerated by nobody (no launchd job runs
build-fleet.js; scheduled-run only READS the file).
These are vendors whose samples went overdue after the
last build. Fixed by regenerating, now that d8486af
makes regeneration safe for the alias stubs.
POI -- has an email as of today but no account_number, and
vidContactMap requires BOTH.
1838 WALLCOVERINGS -- no email, no account, and no canonical FileMaker row.
Note the item list itself is NOT stale — scheduled-run pulls it live from
FileMaker each run. Only the vid->contact bridge is stale, so the failure mode
is silently skipping a vendor, never chasing a dead lead.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Files touched
M scripts/resolve-original-dates.mjsM scripts/scheduled-run.mjs
Diff
commit e343b5f7af18ff8cf72ff06bc0cc740763b4cbb3
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Sat Sep 12 07:41:39 2026 -0700
sample-followup: strip CR/whitespace from FileMaker vid — it was silently dropping chases (TK-11255)
Measured live against FileMaker, not hypothesised: of 129 overdue sample records
in the current 10-60 day window, 11 across 7 vendor codes resolve to NO contact
and are skipped with no error and no log line. One of those is a plain key bug.
A Kravet record's vid is literally "kra\r". scheduled-run.mjs keyed the contact
map with String(vid).toUpperCase() and no trim, so "KRA\r" never matched "KRA"
and that vendor's overdue sample was never chased. Same untrimmed pattern in
resolve-original-dates.mjs. build-fleet.js already strips \r from Mfr Pattern and
client name — vid was simply missed.
This is the silent-skip class: nothing errors, nothing logs, the sample just
never gets chased and a client waits.
Both sites now strip CR/LF and trim before upper-casing.
The other 6 skipped vids are NOT this bug and are deliberately not touched here:
1838, FUT, VAH, BRU -- vid absent from data/fleet.json, which is 29 days stale
and is regenerated by nobody (no launchd job runs
build-fleet.js; scheduled-run only READS the file).
These are vendors whose samples went overdue after the
last build. Fixed by regenerating, now that d8486af
makes regeneration safe for the alias stubs.
POI -- has an email as of today but no account_number, and
vidContactMap requires BOTH.
1838 WALLCOVERINGS -- no email, no account, and no canonical FileMaker row.
Note the item list itself is NOT stale — scheduled-run pulls it live from
FileMaker each run. Only the vid->contact bridge is stale, so the failure mode
is silently skipping a vendor, never chasing a dead lead.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
---
scripts/resolve-original-dates.mjs | 2 +-
scripts/scheduled-run.mjs | 7 ++++++-
2 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/scripts/resolve-original-dates.mjs b/scripts/resolve-original-dates.mjs
index 0c7c716..8cc9c7a 100644
--- a/scripts/resolve-original-dates.mjs
+++ b/scripts/resolve-original-dates.mjs
@@ -56,7 +56,7 @@ const contacts = JSON.parse(readFileSync(new URL('../data/contacts.json', import
const vidRecip = {}; for (const v of fleet) { const c = contacts[v.slug] || {}; const e = c.sample_email || c.main_email; if (e && !vidRecip[String(v.vid || '').toUpperCase()]) vidRecip[String(v.vid || '').toUpperCase()] = e; }
const byVid = {};
-for (const r of A2) { const vid = String(r.fieldData.vid || '').toUpperCase(); if (!vid) continue; (byVid[vid] = byVid[vid] || []).push({ mfr: (r.fieldData['Mfr Pattern'] || '').trim(), fmDate: r.fieldData['today for client'] || '' }); }
+for (const r of A2) { const vid = String(r.fieldData.vid || '').replace(/[\r\n]/g, '').trim().toUpperCase(); if (!vid) continue; (byVid[vid] = byVid[vid] || []).push({ mfr: (r.fieldData['Mfr Pattern'] || '').trim(), fmDate: r.fieldData['today for client'] || '' }); }
let hit = 0, miss = 0;
for (const [vid, rows] of Object.entries(byVid)) {
diff --git a/scripts/scheduled-run.mjs b/scripts/scheduled-run.mjs
index 93ecf70..75dc0e8 100644
--- a/scripts/scheduled-run.mjs
+++ b/scripts/scheduled-run.mjs
@@ -287,7 +287,12 @@ const run = async () => {
const byVid = {};
for (const r of A) {
if (chasedIds.has(String(r.recordId))) continue; // already requested → do not duplicate
- const vid = String(r.fieldData.vid || '').toUpperCase(); if (!vid) continue;
+ // TK-11255: FileMaker vid values carry stray CR/whitespace (measured live: a
+ // Kravet record's vid is literally "kra\r"). Without stripping it the key never
+ // matches cmap and that vendor's overdue sample is SILENTLY skipped -- no error,
+ // no log, it just never gets chased. build-fleet.js already strips \r from other
+ // FileMaker fields; vid was the one that was missed.
+ const vid = String(r.fieldData.vid || '').replace(/[\r\n]/g, '').trim().toUpperCase(); if (!vid) continue;
(byVid[vid] = byVid[vid] || []).push({
recordId: r.recordId, mfr: (r.fieldData['Mfr Pattern'] || '').trim(),
sku: r.fieldData['combo sku'] || '', requested: r.fieldData['today for client'] || '',
← eafdc77 chore: v1.1.0 -> v1.1.1 (TK-11255 vendor-desk routing fix, s
·
back to Sample Followup Sweep
·
contacts.json: unblock POI + 1838, both silently skipped by a1c761a →