Skip to content

Bug: lint phase engine.disconnect() kills worker shared DB pool, causing crash-loop #1499

@justemu

Description

@justemu

Summary

During autopilot cycle execution, the lint phase creates a second PostgresEngine and shares the module-level db.sql singleton via engine.connect({}) (no poolSize). When the phase completes, engine.disconnect() in the finally block destroys the shared pool, rendering the worker unable to operate. All subsequent phases fail, and the worker crashes with an unhandled rejection.

Impact

  • All 9 sources never completed a full cycle
  • Brain score stuck at 51 (links 3/25, timeline 2/15, orphans 1/15)
  • Worker crash-loops: 51 crash records, max 5 restarts before autopilot gives up

Root Cause

src/commands/lint.ts:298-319, resolveLintContentSanity():

const engine = await createEngine({...});
try {
    await engine.connect({});  // no poolSize -> module singleton path
    const lifted = await loadConfigWithEngine(engine, base);
} finally {
    await engine.disconnect(); // -> db.disconnect() -> sql.end(); sql = null
}

engine.connect({}) without poolSize routes through the module-level db.sql singleton. The subsequent engine.disconnect() in the finally block kills the shared pool for ALL callers in the process, including the MinionWorker.

Diagnosis

Instrumented db.disconnect(), PostgresEngine.disconnect(), and getConnection() with stack traces. The stack trace confirms the disconnect originates from resolveLintContentSanity -> lint.ts:319 -> runLintCore -> runPhaseLint -> runCycle.

Fix

Pass poolSize: 2 so the lint engine gets its own instance-level pool that does not share state with the module singleton:

await engine.connect({ poolSize: 2 });

Related

The /No database connection/i pattern in retry-matcher.ts (added v0.41.2.1) marks this terminal error as retryable, producing misleading connection blip log messages and wasting a 500ms retry. Since the error means the module-level singleton is null, retrying without explicit reconnect is guaranteed to fail.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions