Skip to main content

How env validation works

The runtime composes one big Zod schema at boot: the Tier-0 base schema (always required) plus every loaded plugin’s configSchema. process.env is validated against the merged schema. Missing required vars fail boot with [boot-error] Plugin '<name>' env validation failed for '<field>'. Disabling a plugin (via features or autoDetect) removes its env requirements automatically.

Tier-0 (core)

Always required by the runtime. Source: packages/oracle-runtime/src/config/base-env-schema.ts.

Runtime

Matrix

Storage

Blocksync / chain

Auth / UCAN

Always present. Both are z.coerce.number() — set them as plain integer strings in .env.

LLM

Cross-field check (validateLlmProviderKey): the API key for the selected LLM_PROVIDER must be present — OPEN_ROUTER_API_KEY when LLM_PROVIDER=openrouter (the default), NEBIUS_API_KEY when LLM_PROVIDER=nebius. A missing key fails boot with a named-field error (e.g. OPEN_ROUTER_API_KEY / NEBIUS_API_KEY) rather than a generic upstream 401 at request time. The per-role model ids are hardcoded per provider — there is no env var to swap the main model id (use the resolveModel hook for that).

Misc

LangSmith tracing (optional)

Declared in the base schema so they show up in qiforge-cli env output. LangChain auto-wires when these are present in process.env; the runtime never reads them directly.

Per-plugin

Only required when the named plugin is loaded.

Variables read but not owned

Some plugins read variables that live in another schema:
  • composio reads the core NETWORK and forwards it as x-ixo-network.
  • skills reads NETWORK and forwards as X-IXO-Network.
  • sandbox reads ORACLE_SECRETS (core) and SKILLS_CAPSULES_BASE_URL (owned by skills) and forwards them as headers.
These are declared in the plugin’s sibling schemas (typed optional()); a missing value just skips the matching header instead of failing the plugin build.

Generating an .env template

qiforge-cli env generates a .env template for your installed plugin set. Until that lands, write the file by hand using this reference.