ruvnet/ruflo · error
TruthAnchorStore requires a signingKey in config. Anchors ca
Error message
TruthAnchorStore requires a signingKey in config. Anchors cannot be created without a signing key.
What it means
The TruthAnchorStore constructor throws when config.signingKey is absent (undefined or empty). Every truth anchor is HMAC-signed and immutable once appended, so the store cannot create or verify anchors without a key — there is deliberately no unsigned mode. This is a fail-fast configuration check at construction time.
Source
Thrown at v3/@claude-flow/guidance/src/truth-anchors.ts:205
// ============================================================================
/**
* Append-only store for truth anchors.
*
* Anchors are immutable once created. The store provides signing,
* verification, querying, supersession, and capacity management
* with LRU eviction of expired anchors only.
*/
export class TruthAnchorStore {
private readonly config: TruthAnchorConfig;
private readonly anchors: TruthAnchor[] = [];
private readonly indexById: Map<string, number> = new Map();
constructor(config: Partial<TruthAnchorConfig> = {}) {
this.config = { ...DEFAULT_CONFIG, ...config };
if (!this.config.signingKey) {
throw new Error(
'TruthAnchorStore requires a signingKey in config. ' +
'Anchors cannot be created without a signing key.',
);
}
}
/**
* Create and sign a new truth anchor.
*
* The anchor is appended to the store and can never be mutated.
* If the store exceeds capacity, expired anchors are evicted
* starting from the oldest.
*/
anchor(params: AnchorParams): TruthAnchor {
const now = Date.now();
const partial: Omit<TruthAnchor, 'signature'> = {
id: randomUUID(),View on GitHub (pinned to fa13ee4ad6)
Solutions
- Pass a non-empty signingKey: new TruthAnchorStore({ signingKey: process.env.TRUTH_ANCHOR_KEY })
- If no external key exists, generate a stable secret once (e.g. random 32-byte hex stored in your secret manager) and reuse it — the same key must verify previously created anchors
- Fail fast at config-load time by asserting required secrets before constructing the store
Example fix
// before
const store = new TruthAnchorStore(); // throws: signingKey required
// after
const store = new TruthAnchorStore({
signingKey: process.env.TRUTH_ANCHOR_SIGNING_KEY!,
}); Defensive patterns
Strategy: validation
Validate before calling
// Resolve the key before constructing the store
const signingKey = process.env.TRUTH_ANCHOR_SIGNING_KEY;
if (!signingKey) {
throw new Error('TRUTH_ANCHOR_SIGNING_KEY is required to start this service');
}
const store = new TruthAnchorStore({ signingKey }); Type guard
type SignedStoreConfig = Partial<TruthAnchorConfig> & { signingKey: string };
function hasSigningKey(c: Partial<TruthAnchorConfig>): c is SignedStoreConfig {
return typeof c.signingKey === 'string' && c.signingKey.length > 0;
} Prevention
- Check required secrets at config-load time with a single bootstrap assertion
- Use one stable signing key per environment; rotating it invalidates verification of old anchors
- Include TruthAnchorStore construction in smoke tests so missing keys fail CI, not prod
When it happens
Trigger: Calling new TruthAnchorStore() with no arguments, or with a config object whose signingKey is undefined/empty string — typically because the key was read from an environment variable or secret manager entry that was never set in the current environment.
Common situations: Key configured in the production profile but missing in CI or local dev; secrets loaded asynchronously after the store is constructed; a Partial<TruthAnchorConfig> built from sparse JSON where the signingKey field is absent; refactoring that renamed the config field.
Related errors
- ArtifactLedger requires an explicit signingKey — hardcoded d
- ConformanceRunner requires an explicit signingKey
- EvolutionPipeline requires an explicit signingKey — hardcode
- ProofChain requires an explicit signingKey — hardcoded defau
- Root guidance file not found: ${this.config.rootGuidancePath
AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18).
Data as JSON: /api/errors/6c381d48d2c92c39.
Report an issue: GitHub.