Summary
HARPER_BUILTIN_COMPONENTS is a comma-separated name=packageIdentifier list. getEnvBuiltInComponents() (components/Application.ts:1876) destructures each entry on = and returns packageIdentifier: undefined for a bare name (no =value) — it doesn't validate or reject that shape.
Two separate call sites then dereference the resulting undefined packageIdentifier without a guard:
components/Application.ts:1129, inside installApplications(), which runs at boot.
server/jobs/jobProcess.ts:39, packageIdentifier.startsWith('@/').
Concrete failure scenario
An operator (or CI config) sets HARPER_BUILTIN_COMPONENTS=secretCustody (forgetting the =value part, which the parser otherwise permits as valid syntax). installApplications() dereferences the undefined packageIdentifier at boot and throws a TypeError — the whole Harper process fails to start, from what looks like a harmless typo.
Suggested fix
Reject or skip malformed (missing =value) definitions at the source, in getEnvBuiltInComponents() itself, rather than guarding each of the (at least two) consumer call sites individually.
Provenance
Found while writing integrationTests/server/qa577-upgrade-builtins.test.ts (a stand-in @/-prefixed built-in registration for testing PR #1814's config backfill) — trying a real npm-installable name first (lodash) surfaced the parser's tolerance of a bare name, which led to finding this. Orthogonal to #1814's own diff; not exercised by that test file, just documented there.
🤖 Filed by Claude (dispatch pr-fix agent) while addressing review comments on #1972.
Summary
HARPER_BUILTIN_COMPONENTSis a comma-separatedname=packageIdentifierlist.getEnvBuiltInComponents()(components/Application.ts:1876) destructures each entry on=and returnspackageIdentifier: undefinedfor a bare name (no=value) — it doesn't validate or reject that shape.Two separate call sites then dereference the resulting
undefinedpackageIdentifier without a guard:components/Application.ts:1129, insideinstallApplications(), which runs at boot.server/jobs/jobProcess.ts:39,packageIdentifier.startsWith('@/').Concrete failure scenario
An operator (or CI config) sets
HARPER_BUILTIN_COMPONENTS=secretCustody(forgetting the=valuepart, which the parser otherwise permits as valid syntax).installApplications()dereferences the undefined packageIdentifier at boot and throws aTypeError— the whole Harper process fails to start, from what looks like a harmless typo.Suggested fix
Reject or skip malformed (missing
=value) definitions at the source, ingetEnvBuiltInComponents()itself, rather than guarding each of the (at least two) consumer call sites individually.Provenance
Found while writing
integrationTests/server/qa577-upgrade-builtins.test.ts(a stand-in@/-prefixed built-in registration for testing PR #1814's config backfill) — trying a real npm-installable name first (lodash) surfaced the parser's tolerance of a bare name, which led to finding this. Orthogonal to #1814's own diff; not exercised by that test file, just documented there.🤖 Filed by Claude (dispatch pr-fix agent) while addressing review comments on #1972.