Summary
gbrain sync/ingest crashes in assessContentSanity() when a page's parsed title is undefined:
opts.title.toLowerCase is not a function. (In 'opts.title.toLowerCase()', 'opts.title.toLowerCase' is undefined)
This is the crash from #1556, which the original reporter closed as "premature, filed while validating a local install — will file fresh after confirming against a clean/current install." Confirming here against current master.
Environment
Root cause
src/core/content-sanity.ts types the param as title: string (non-optional):
export function assessContentSanity(opts: {
...
title: string; // <- callers can pass undefined at runtime
...
}) {
...
const titleLower = opts.title.toLowerCase(); // throws
...
if (p.pattern.test(opts.title)) ... // also unsafe
}
But src/core/import-file.ts (and sources.ts, lint.ts, doctor.ts) call it with title: parsed.title, and parsed.title is undefined whenever a page has no title: frontmatter field. This bites two ways:
- Title-less pages (e.g. daily/date notes with no
title:).
- History replay:
sync replays git history commit-by-commit; a page that has a title: today did not at the historical commits being replayed, so parsed.title is genuinely undefined for those revisions and the whole sync run aborts.
Repro
A markdown file with no title: in frontmatter, then gbrain sync (or import). assessContentSanity throws on the first such page.
Fix
Coerce defensively at the single choke point (covers all four callers) and make the type honest:
title?: string | null;
// ...
const title = String(opts.title ?? '');
const titleLower = title.toLowerCase();
// ...
if (p.pattern.test(title)) ...
All 76 existing content-sanity tests pass; null/undefined/number/empty/string inputs all return a result instead of throwing. PR incoming.
Summary
gbrain sync/ingest crashes inassessContentSanity()when a page's parsed title isundefined:This is the crash from #1556, which the original reporter closed as "premature, filed while validating a local install — will file fresh after confirming against a clean/current install." Confirming here against current
master.Environment
041d89b(v0.41.29.0)openai:text-embedding-3-small~/.gbrain/sync-failures.jsonl, all dated right afterv0.41.26.0(v0.41.26.0 fix: dream --source + ingest junk titles + emoji-crash (supersedes #1559, #1561) #1571) landed the junk-title content-sanity check.Root cause
src/core/content-sanity.tstypes the param astitle: string(non-optional):But
src/core/import-file.ts(andsources.ts,lint.ts,doctor.ts) call it withtitle: parsed.title, andparsed.titleisundefinedwhenever a page has notitle:frontmatter field. This bites two ways:title:).syncreplays git history commit-by-commit; a page that has atitle:today did not at the historical commits being replayed, soparsed.titleis genuinelyundefinedfor those revisions and the whole sync run aborts.Repro
A markdown file with no
title:in frontmatter, thengbrain sync(or import).assessContentSanitythrows on the first such page.Fix
Coerce defensively at the single choke point (covers all four callers) and make the type honest:
All 76 existing
content-sanitytests pass;null/undefined/number/empty/string inputs all return a result instead of throwing. PR incoming.