Skip to content

bug: read-only knowledge store connection always fails due to DuckDB same-file constraint #627

Description

@mickume

Summary

Starting af code always emits a noisy WARNING + full traceback because _setup_infrastructure tries to open a read-only DuckDB connection to the same knowledge store file that already has an active read-write connection. DuckDB does not allow mixed read_only configurations on the same database file within a single process.

Reproduction

af code

Observe in the output:

[WARNING] agentfox.engine.run: Failed to open read-only knowledge store for context assembly; falling back to main connection
…
_duckdb.ConnectionException: Connection Error: Can't open a connection to same database file with a different configuration than existing connections

Root Cause

In packages/agentfox/agentfox/engine/run.py, _setup_infrastructure:

  • Line 109: opens a read-write connection — open_knowledge_store(config.knowledge, read_only=False)
  • Line 118: attempts a read-only connection to the same fileopen_knowledge_store(config.knowledge, read_only=True)

DuckDB (1.5.4) enforces that all in-process connections to a given file share the same read_only flag. The second call always fails.

The pattern was introduced in commit a053f869 for requirement 06-REQ-7.3 ("ensure assemble_context never holds a write lock"). The fallback on lines 119–123 catches the error and reuses the main connection, so the application runs — but:

  1. The traceback is alarming and confusing to users.
  2. The original intent (lock-free reads during context assembly) is silently defeated.

Impact

  • Every af code invocation prints a multi-line traceback that looks like a crash.
  • The read-only separation goal of 06-REQ-7.3 is never achieved in practice.

Suggested Fix

Replace the separate read_only=True connection with a cursor from the existing read-write connection:

# Current (always fails):
context_knowledge_db = open_knowledge_store(config.knowledge, read_only=True)

# Proposed:
context_cursor = knowledge_db.connection.cursor()

DuckDB supports multiple cursors on a single connection, allowing concurrent reads without a separate connection object. The context assembly code would receive the cursor (or a thin wrapper) instead of a full KnowledgeDB instance.

This satisfies the spirit of 06-REQ-7.3 — context reads don't contend with write queries — without violating DuckDB's same-file configuration constraint.

Files Involved

  • packages/agentfox/agentfox/engine/run.py_setup_infrastructure (primary fix site)
  • packages/agentfox/agentfox/knowledge/db.py — may need a helper to expose a cursor wrapper

Metadata

Metadata

Assignees

No one assigned

    Labels

    af:fixIssues ready to be implementedaf:fixed

    Type

    No type
    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