Skip to content

init: GBRAIN_EMBEDDING_MODEL/DIMENSIONS env vars ignored when no config.json AND no DATABASE_URL #1058

@vincedk-alt

Description

@vincedk-alt

Summary

On a fresh install (no ~/.gbrain/config.json AND no DATABASE_URL), gbrain init --pglite ignores GBRAIN_EMBEDDING_MODEL and GBRAIN_EMBEDDING_DIMENSIONS env vars. The init silently defaults to OpenAI 1536, even when the user has explicitly set their preferred provider via shell env.

Repro on v0.35.1.0

# Fresh machine, no config.json, no DATABASE_URL
rm -f ~/.gbrain/config.json
rm -rf ~/.gbrain/brain.pglite

# Set env vars expecting them to take effect
export GBRAIN_EMBEDDING_MODEL=lmstudio:text-embedding-nomic-embed-text-v1.5
export GBRAIN_EMBEDDING_DIMENSIONS=768

# Run plain init
gbrain init --pglite

Result: column comes up at vector(1536) with text-embedding-3-large as the configured model. First embed against LM Studio returns 768-dim, sync explodes with expected 1536 dimensions, not 768.

Root cause

loadConfig() at src/core/config.ts:135 early-returns null when neither fileConfig nor dbUrl is set:

if (!fileConfig && !dbUrl) return null;

Env-var merge logic below that early-return (config.ts:153-176) never runs. The init's resolveAIOptions sees null and falls through to gateway defaults. The env vars ARE honored when there's already a config.json or a DATABASE_URL (both make loadConfig return non-null, then the merge step runs) — but not in the env-only cold-start case.

Workaround

Pre-create config.json before running init. After config.json exists, env vars are honored (loadConfig returns non-null, merge step runs, env vars override file).

Suggested fix shapes (any of)

A. Sibling helper loadAIConfig() that reads ONLY embedding/expansion/chat fields from env + file, no inferredEngine logic. Called from resolveAIOptions in addition to loadConfig. Smallest blast radius; doesn't touch any existing call site.

B. loadConfig early-return refactor — extend the gate so AI-related env vars also bypass the early return, returning a partial config with just AI fields populated. Risk: inferredEngine defaults to 'postgres' for PGLite users (config.ts:143-145), which would silently misroute PGLite users to Postgres setup. Needs careful inferredEngine handling.

C. Document the workaround in install docs. Lowest engineering cost but worst DX.

I'd vote (A) — it gives env-only callers parity with config-file callers without modifying the load-config contract that downstream code relies on.

Context

Discovered while reviewing the patch for #203 (config.json-is-ignored case). That fix lands resolveAIOptions reading loadConfig() first, which works for users who HAVE a config.json. The env-only path remains stranded as a separate bug class. Test case 5 in test/init-config-first.test.ts (in the #203 PR) pins the current (limited) behavior so any future fix is loud.

Related issues:

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