Skip to content

HARPER_SET_CONFIG applied after component loading (thread-timing race) and not persisted at install — env-var-configured components silently fail to register #1618

Description

@heskew

Summary

HARPER_SET_CONFIG (and by extension env-var-driven config) is unreliable for anything component-loading reads at boot: it is applied to the in-memory config after components load on some platforms/timings, and the install-time application does not persist it to the written config file. Net effect: a component key delivered via env var may be silently ignored — the component never registers, no error, no warning.

Found while debugging PR #1616's integration-test 404s (the modelsGateway component); the mechanism is general and affects any env-var-configured deployment (Docker/Fabric-style) activating or configuring components via HARPER_SET_CONFIG.

Evidence

1. Ordering race (Linux CI, deterministic there; opposite on macOS). From the failing suite's Harper instance log (PR #1616, run 28810803532, shard 4/6):

17:37:26.137 [main/0] [info]:  All root applications loaded          ← componentLoader ran
17:37:26.494 [http/1] [debug] [env-config]: Applied HARPER_SET_CONFIG at runtime   ← merged after
17:37:26.507 [http/1] [debug]: Config file updated with runtime env var values

Components were loaded from a config that did not yet contain the env-supplied key → /v1/* 404s. The same boot on macOS serves 200 — the runtime application happens to win there. Same code, thread-timing-dependent outcome.

2. Install-time application doesn't persist. config/configUtils.ts:163 calls applyRuntimeEnvVarConfig(configDoc, null, { isInstall: true }) before writing the fresh config file — but after a fresh local install with HARPER_SET_CONFIG='{"modelsGateway":{"enabled":true}}', the written harperdb-config.yaml does not contain the key (verified directly). So even a fresh install under env config produces a file that component loading can't see the env config in, leaving only the racy runtime path (configUtils.ts:341).

(There is also a known sub-issue that flattenObject in config/harperConfigEnvVars.ts silently drops empty-object values like modelsGateway: {} — no leaf paths — noted in PR #1616's history. The non-empty {enabled: true} form still hits the two problems above, so fixing the flatten alone is insufficient.)

Why this matters

  • Env-var config is the primary mechanism for containerized deployments and the integration-test harness (@harperfast/integration-testing passes suite config exclusively via HARPER_SET_CONFIG — see its harperLifecycle).
  • Silent mis-registration: nothing logs that a component key arrived too late to matter.
  • Direction from Nathan: fix the core loading order properly rather than working around it (e.g., PR feat(models): OpenAI-compatible /v1/* gateway as built-in Resources (#631, Phase 4 of #510) #1616 deliberately keeps its component default-off and its integration test depends on this fix; enabling things by default to dodge the race is not an acceptable pattern).

Suggested shape of the fix

  • Apply HARPER_DEFAULT_CONFIG / HARPER_CONFIG / HARPER_SET_CONFIG synchronously during initial config resolution on every thread, before any component loading — i.e. the resolved config object handed to componentLoader must already include env-var config, deterministically, on all platforms.
  • Make the install-time application actually persist into the freshly written config file (or make the boot path not depend on the file for env-supplied values).
  • Keep the existing drift-detection/restore semantics (hasPersistedEnvConfigState) intact.
  • Consider a debug log when env config introduces keys that affect component activation, to make future ordering regressions visible.

Acceptance

Refs


🤖 Generated with Claude Code

Metadata

Metadata

Assignees

Labels

duplicateThis issue or pull request already exists

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions