ruvnet/ruflo · error

No policy bundle loaded. Call loadBundle() first.

Error message

No policy bundle loaded. Call loadBundle() first.

What it means

PolicyRetriever.retrieve() requires a compiled PolicyBundle to have been loaded via loadBundle() — it throws while this.constitution is still unset. The same state is observable via the public getConstitution() accessor (null when unloaded). When the retriever is used inside GuidanceControlPlane, initialize() performs the load, so standalone usage that skips loadBundle() is the usual cause.

Source

Thrown at v3/@claude-flow/guidance/src/retriever.ts:352

    const confidence = Math.min(bestScore / 3, 1);

    return { intent: bestIntent, confidence };
  }

  /**
   * Retrieve relevant shards for a task
   *
   * Contract:
   * 1. Always include the constitution
   * 2. Up to maxShards by semantic similarity
   * 3. Hard filters by risk class and repo scope
   * 4. Contradiction check: prefer higher priority
   */
  async retrieve(request: RetrievalRequest): Promise<RetrievalResult> {
    const startTime = performance.now();

    if (!this.constitution) {
      throw new Error('No policy bundle loaded. Call loadBundle() first.');
    }

    // Step 1: Classify intent
    const { intent: detectedIntent } = this.classifyIntent(request.taskDescription);
    const intent = request.intent ?? detectedIntent;

    // Step 2: Generate query embedding
    const queryEmbedding = await this.embeddingProvider.embed(request.taskDescription);

    // Step 3: Score all shards
    const maxShards = request.maxShards ?? 5;
    const scored = this.scoreShards(queryEmbedding, intent, request.riskFilter, request.repoScope);

    // Step 4: Select top N with contradiction resolution
    const selected = this.selectWithContradictionCheck(scored, maxShards);

    // Step 5: Build combined policy text
    const policyText = this.buildPolicyText(this.constitution, selected);

View on GitHub (pinned to fa13ee4ad6)

Solutions

  1. Await retriever.loadBundle(bundle) before the first retrieve() call
  2. Or use GuidanceControlPlane and await plane.initialize(), which loads the bundle for you
  3. Guard with retriever.getConstitution() !== null before dispatching retrieval requests
  4. Order startup so bundle compilation/loading completes before request handling begins

Example fix

// before
const retriever = new PolicyRetriever(embedder);
await retriever.retrieve({ taskDescription: 'refactor db' }); // throws
// after
const retriever = new PolicyRetriever(embedder);
await retriever.loadBundle(compiledBundle);
await retriever.indexShards();
await retriever.retrieve({ taskDescription: 'refactor db' });
Defensive patterns

Strategy: validation

Validate before calling

if (retriever.getConstitution() === null) {
  const bundle = await compileGuidance(rootContent, localContent); // or plane.getBundle()
  await retriever.loadBundle(bundle);
  await retriever.indexShards();
}
await retriever.retrieve(request);

Type guard

function isRetrieverLoaded(retriever: PolicyRetriever): boolean {
  return retriever.getConstitution() !== null;
}

Prevention

When it happens

Trigger: Constructing new PolicyRetriever(provider) and calling retrieve() without awaiting loadBundle(); a loadBundle() call that failed earlier; using the retriever standalone (outside the control plane) in scripts or tests.

Common situations: Ad-hoc retrieval scripts; unit tests that instantiate the retriever directly; refactors that bypass the control plane and forget the load step.

Related errors


AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18). Data as JSON: /api/errors/edae3cb0007f3e17. Report an issue: GitHub.