jackwener/OpenCLI · warning · Error

Verify command returned no metric for baseline

Error message

Verify command returned no metric for baseline

What it means

pruneTraceArtifactsBestEffort in src/observation/artifact.ts wraps pruneTraceArtifacts in try/catch and, on failure, only logs '[trace] Failed to prune trace artifacts: <message>' via log.warn. This is intentionally best-effort: pruning old trace artifacts after exportObservationSession must never fail the export, so any error (permissions, missing dirs, locked files) is downgraded to a warning carrying the underlying error message.

Source

Thrown at autoresearch/engine.ts:183

    ];
    return hints[Math.min(discards - 5, hints.length - 1)];
  }

  /** Run the main loop */
  async run(): Promise<IterationResult[]> {
    const results: IterationResult[] = [];

    // Phase 0: Preconditions
    this.log('Phase 0: Precondition checks...');
    this.checkPreconditions();

    // Initialize logger
    this.logger.init(this.config);

    // Baseline measurement
    this.log('Measuring baseline...');
    const baseline = this.runVerify();
    if (baseline == null) throw new Error('Verify command returned no metric for baseline');
    this.bestMetric = baseline;
    this.currentMetric = baseline;

    const baselineCommit = exec('git rev-parse --short HEAD');
    const baselineResult: IterationResult = {
      iteration: 0,
      commit: baselineCommit,
      metric: baseline,
      delta: 0,
      guard: this.config.guard ? (this.runGuard() ? 'pass' : 'fail') : '-',
      status: 'baseline',
      description: `initial state — ${this.config.metric} ${baseline}`,
    };
    this.logger.append(baselineResult);
    results.push(baselineResult);
    this.log(`Baseline: ${this.config.metric} = ${baseline}`);

    // Main loop

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Check the log's embedded message (err.message) to identify the underlying fs error (ENOENT, EACCES, EBUSY, etc.).
  2. Verify the traces directory exists and the process user has write/delete permissions on it and its contents.
  3. Close other processes/locks holding trace files open, then re-run the export/prune.
  4. If pruning is optional for your workflow, treat the warning as non-fatal — the observation session export itself succeeded; manually clean old trace dirs as needed.
Defensive patterns

Strategy: fallback

Validate before calling

import { accessSync, constants } from 'fs';
try {
  accessSync(tracesDir, constants.W_OK);
} catch {
  log.warn(`[trace] tracesDir ${tracesDir} not writable — pruning will be skipped`);
}

Type guard

function canPrune(tracesDir: string): boolean {
  try { accessSync(tracesDir, constants.W_OK); return true; } catch { return false; }
}

Try / catch

// the library already swallows this; on your side treat it as non-fatal:
try {
  await exportObservationSession(session);
} catch (err) {
  throw err; // pruning failures do NOT surface here — only as '[trace] Failed to prune...' warnings
}
// match on the log warning if you want to schedule manual cleanup

Prevention

When it happens

Trigger: exportObservationSession calls pruneTraceArtifacts with a retention policy and protectedTraceDir, and the pruning step throws — e.g. the tracesDir doesn't exist, files are read-only, or the OS denies deletion.

Common situations: Running the daemon under a user without write/delete permission on the traces directory; tracesDir on a read-only or removed volume; another process holding trace files open (Windows file locks); a corrupted or partially deleted trace directory from a previous crash.

Related errors


AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29). Data as JSON: /api/errors/136be849d9423e4d. Report an issue: GitHub.