Skip to content

fix: per-repo resolver must not overwrite explicit CGC_RUNTIME_DB_TYPE#1254

Open
aprotteau-dac wants to merge 1 commit into
CodeGraphContext:mainfrom
aprotteau-dac:fix/per-repo-env-override
Open

fix: per-repo resolver must not overwrite explicit CGC_RUNTIME_DB_TYPE#1254
aprotteau-dac wants to merge 1 commit into
CodeGraphContext:mainfrom
aprotteau-dac:fix/per-repo-env-override

Conversation

@aprotteau-dac

Copy link
Copy Markdown

Problem

Two related bugs that combine to produce silent backend mis-routing — most visibly on Windows, where FalkorDB Lite (database: falkordb) is unavailable and the fallback to KuzuDB fails with -32000 / Failed to reconnect and leaves a zombie cgc mcp start process.

Bug 1 — server.py: resolver verdict unconditionally overwrites process env

MCPServer.__init__ does:

if ctx.database:
    os.environ['CGC_RUNTIME_DB_TYPE'] = ctx.database

This overwrites any value the caller already placed in the process env — e.g. CGC_RUNTIME_DB_TYPE=falkordb-remote set by a project .mcp.json env block or a launcher wrapper — with whatever resolve_context() defaulted to. The user's explicit backend choice is silently discarded.

Bug 2 — config_manager.py: per-repo branch ignores process env for the default

When resolve_context() takes the per-repo branch (a local .codegraphcontext/ folder is present), it initialises local_db via:

local_db = load_config().get("DEFAULT_DATABASE", "falkordb")

load_config() reads .env files from disk. It does not consult the current process environment. So CGC_RUNTIME_DB_TYPE=falkordb-remote in the MCP launcher env is invisible here and the resolver defaults to bare "falkordb".

Combined failure mode (Windows + per-repo folder)

A repo that has a .codegraphcontext/ folder (common — e.g. for a repo-local .cgcignore) but no explicit config.yaml pin will:

  1. Take the per-repo branch → local_db = "falkordb" (Bug 2)
  2. Write that back to CGC_RUNTIME_DB_TYPE (Bug 1), discarding falkordb-remote
  3. get_database_manager() picks up "falkordb" → FalkorDB Lite unavailable on Windows → silent KuzuDB fallback → single-writer lock crash → -32000 and a zombie process

Fix

server.py — only write when the variable is not already explicitly set:

if ctx.database and not os.environ.get('CGC_RUNTIME_DB_TYPE'):
    os.environ['CGC_RUNTIME_DB_TYPE'] = ctx.database

config_manager.py — consult process env before file-based config:

local_db = (
    os.environ.get("CGC_RUNTIME_DB_TYPE")
    or os.environ.get("DEFAULT_DATABASE")
    or load_config().get("DEFAULT_DATABASE", "falkordb")
)

An explicit database: key in the repo-local config.yaml still wins over all of the above (local_raw.get("database", local_db)), so per-repo config pins continue to work as documented.

Workaround (until a release picks this up)

Add a .codegraphcontext/config.yaml pinning database: falkordb-remote to any repo using the remote backend that carries a local .codegraphcontext/ folder. This makes local_raw.get("database", local_db) return "falkordb-remote" and bypasses both bugs.

Tested against

Reproduced against v0.4.12 (PyPI). Fix validated end-to-end: MCP server connects to FalkorDB remote, list_indexed_repositories returns correct graph, no KuzuDB fallback log.

…E_DB_TYPE

Two related bugs that together cause silent backend mis-routing, particularly
on Windows where FalkorDB Lite is unavailable:

**Bug 1 — server.py: resolver verdict unconditionally overwrites process env**

`MCPServer.__init__` sets `os.environ["CGC_RUNTIME_DB_TYPE"] = ctx.database`
whenever `resolve_context()` returns a non-empty `database` field. This
overwrites any value the user (or launcher wrapper) already placed in the
process env — e.g. via `CGC_RUNTIME_DB_TYPE=falkordb-remote` in a project's
`.mcp.json` env block — with whatever the resolver defaulted to.

Fix: only write when the variable is not already set:
  `if ctx.database and not os.environ.get("CGC_RUNTIME_DB_TYPE"):`

**Bug 2 — config_manager.py: per-repo branch ignores process env for default**

When `resolve_context()` takes the per-repo branch (local `.codegraphcontext/`
folder present), it initialises `local_db` from
`load_config().get("DEFAULT_DATABASE", "falkordb")`. `load_config()` reads
`.env` files from disk; it does not consult the current process environment.
So `CGC_RUNTIME_DB_TYPE=falkordb-remote` in the MCP launcher env is invisible
here and the resolver defaults to bare `"falkordb"`.

Fix: check process env before file-based config:
  `local_db = (os.environ.get("CGC_RUNTIME_DB_TYPE")
               or os.environ.get("DEFAULT_DATABASE")
               or load_config().get("DEFAULT_DATABASE", "falkordb"))`

An explicit `database:` key in the repo-local `config.yaml` still takes
precedence over all of the above (`local_db = local_raw.get("database", local_db)`).

**Combined failure mode (Windows + per-repo folder)**

With both bugs active: a repo with a `.codegraphcontext/` folder but no
pinning `config.yaml` causes the per-repo branch to fire, default to
`database="falkordb"` (Lite), write that back to `CGC_RUNTIME_DB_TYPE`, and
then `get_database_manager()` picks up "falkordb". FalkorDB Lite is
unavailable on Windows (`core/__init__.py:93-98` falls back to KuzuDB). The
KuzuDB single-writer lock then crashes `cgc mcp start` with a -32000 error,
leaving a zombie process and silently discarding the `falkordb-remote`
settings the user configured.

**Workaround** (still needed until this is released): add a
`.codegraphcontext/config.yaml` pinning `database: falkordb-remote` to any
repo that uses the remote backend and carries a local `.codegraphcontext/`
folder.
@vercel

vercel Bot commented Jun 15, 2026

Copy link
Copy Markdown

@aprotteau-dac is attempting to deploy a commit to the shashankss1205's projects Team on Vercel.

A member of the Team first needs to authorize it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Backlog tasks

Development

Successfully merging this pull request may close these issues.

1 participant