Agent skill

Flowfile Config and Flags Catalog

by Edwardvaneechoud in Edwardvaneechoud/Flowfile

Catalog of Flowfile's environment variables and runtime flags: what each does, where the code reads it, its default, and where the docs disagree with the code.

MITAuto-check: notesDevelopment

Install Flowfile Config and Flags Catalog

skills CLI
$ npx skills add Edwardvaneechoud/Flowfile --skill flowfile-config-and-flags -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install Edwardvaneechoud/Flowfile flowfile-config-and-flags --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/Edwardvaneechoud/Flowfile.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.claude/skills/flowfile-config-and-flags .claude/skills/flowfile-config-and-flags && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
flowfile-config-and-flags
GitHub stars
375
Token cost
~12k tokens
SKILL.md length
4,483 words
Files
1
Skills in repo
19
Repo updated
First seen
Licence
MIT

At a glance

Catalog of Flowfile's environment variables and runtime flags: what each does, where the code reads it, its default, and where the docs disagree with the code.

  • Works in 8 steps: The three config layers → FLOWFILE_MODE — semantics per value → Master env-var table → …
  • Adding or changing an environment variable that Flowfile reads
  • SKILL.md covers When NOT to use this skill, 1. The three config layers, 2. FLOWFILE_MODE — semantics… and 3. Master env-var table, plus 3 more sections
  • Calls make, poetry and python; needs FLOWFILE_INTERNAL_TOKEN and JWT_SECRET_KEY

What it does

This skill is a catalog of how the Flowfile project is configured. Flowfile has no central config schema: about 90 environment variables are read ad hoc across six packages, plus a few runtime-mutable flags and four Starlette Config keys. The skill records what each variable does, which file and line reads it, its default and how it parses truthy values, and where CLAUDE.md, `.env.example`, compose files and docs disagree with the code.

It explains three config layers: plain environment variables; a Starlette `Config` that reads a `.env` file from the process's working directory for just four keys, so the file used depends on where `flowfile_core` is launched; and `MutableBool` flags that an environment variable seeds at boot but an admin HTTP endpoint can flip live without a restart. A section covers how `FLOWFILE_MODE` behaves for each value, with electron as the default alongside docker and package modes.

A when-not-to-use list sends build and launch questions, architecture contracts, the AI subsystem, test infrastructure, live incident debugging and node development to sibling Flowfile skills. The available text ends within the `FLOWFILE_MODE` section.

When your agent uses it

  • Adding or changing an environment variable that Flowfile reads
  • Debugging a config value that is not taking effect
  • Writing a .env or docker-compose entry for Flowfile
  • Auditing which FLOWFILE_ variables exist and where they are documented

Example prompts

  • “What environment variables does Flowfile read, and what are their defaults?”
  • “My FLOWFILE_MODE setting isn't taking effect when I launch the core service. Why?”
  • “How do I flip a feature flag without restarting the server?”
  • “Check whether .env.example matches the variables the code actually reads.”

Requirements

  • A checkout of the Flowfile repository

Workflow steps

8 steps, taken from the step headings in SKILL.md.

  1. The three config layers
  2. FLOWFILE_MODE — semantics per value
  3. Master env-var table
  4. MutableBool — flipping a feature flag without restart
  5. Parsing quirks — truthy rules are NOT uniform
  6. Drift report (both directions)
  7. Add-a-config-axis checklist
  8. Quick reference: minimal env per deployment

What it can do on your machine

Read from SKILL.md and the folder at commit 13aa287. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    Shell commands in SKILL.md call:

    • make
    • poetry
    • python
    • gunicorn

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    No URLs in SKILL.md.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names these keys or tokens, usually read from environment variables:

    • FLOWFILE_INTERNAL_TOKEN
    • JWT_SECRET_KEY
    • FLOWFILE_MASTER_KEY
    • FLOWFILE_ADMIN_PASSWORD
    • ANTHROPIC_API_KEY
    • OPENAI_API_KEY
    • GEMINI_API_KEY
    • GOOGLE_API_KEY
    • GROQ_API_KEY
    • OPENROUTER_API_KEY
    • GOOGLE_OAUTH_CLIENT_SECRET
    • ROOT_PASSWORD

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Flowfile Config and Flags Catalog loads about 12k tokens when it runs. Until then it costs about 160 tokens; SKILL.md has 4,483 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~160
When it runs · the whole SKILL.md, loaded when a task matches
~12k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check: notes

The automated check noted patterns worth knowing about, such as sudo or a known installer.

  • NoteMentions a .env fileSKILL.md:3
    ue "isn't taking effect", when writing a .env or docker-compose entry, or when asked "what env vars does Flowfile read"
  • NoteMentions a .env fileSKILL.md:29
    2. **Starlette `Config(".env")`** — `flowfile_core/flowfile_core/configs/settings.py:129`, `config = Config(".env")`. Re
  • NoteMentions a .env fileSKILL.md:83
    gs.py:133 (Starlette Config: env or CWD `.env`) | `get_default_worker_url(WORKER_PORT)` — `http://{WORKER_HOST}:{port}`
  • NoteMentions a .env fileSKILL.md:194
    lve`: **env var wins over the project's `.env`**) | Supplies values for `${secret:NAME}` placeholders when importing a g
  • NoteMentions a .env fileSKILL.md:226
    keys (settings.py:129-133 — env var OR `.env` in the process CWD)
  • NoteMentions a .env fileSKILL.md:259
    — surviving a restart is the operator's `.env`'s job, not this endpoint's. `GET /system/feature_flags/ai` reads current
  • NoteMentions a .env fileSKILL.md:303
    ler unless you set it yourself; a fresh `.env` copied from `.env.example` for a **non-compose** docker run also won't st
  • NoteMentions a .env fileSKILL.md:320
    estly — do not silently write back to a `.env` file.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from Edwardvaneechoud/Flowfile at commit 13aa287, republished under its MIT licence (© Edwardvaneechoud). 4,483 words, ~11,683 tokens.

Download SKILL.mdSave it as .claude/skills/flowfile-config-and-flags/SKILL.md (or your agent's skills folder).
name
flowfile-config-and-flags
description
Complete catalog of every Flowfile environment variable and runtime flag (FLOWFILE_MODE semantics, MutableBool live-flip flags, storage/database/catalog/AI/kernel/artifact/OAuth vars), which file:line reads each one, its default and truthy-parsing rule, and the documented-vs-actual drift between CLAUDE.md/.env.example/compose/docs — use when adding, changing, debugging, or auditing any FLOWFILE_*/env-var-driven behavior, when a config value "isn't taking effect", when writing a .env or docker-compose entry, or when asked "what env vars does Flowfile read" / "how do I flip a feature flag without restarting".

Flowfile configuration and feature flags

Flowfile has no central config schema — ~90 environment variables are read ad hoc across 6 packages via os.environ/os.getenv, plus a handful of runtime-mutable flags and 4 Starlette-Config keys. This skill is the single source of truth for "what does this var do and where is it read." Read it before touching any FLOWFILE_* variable, .env.example, or docker-compose.yml env block.

When NOT to use this skill

  • How to build/install/launch each service (Poetry, npm, Makefile targets, Docker Compose usage) → flowfile-build-and-env / flowfile-run-and-operate.
  • Why core never .collect()s, or the core↔worker↔kernel data-flow contract → flowfile-architecture-contract.
  • AI provider registry, BYOK, agents, prompt-log format beyond the FEATURE_FLAG_AI gate → flowfile-ai-subsystem.
  • Test markers, fixtures, Docker test infra beyond the env-var names → flowfile-testing-and-validation.
  • Debugging a live incident step-by-step (this skill tells you what a var does; the playbook tells you how to investigate) → flowfile-debugging-playbook.
  • Adding a new node type's config schema (Pydantic node settings, not env vars) → flowfile-node-development.

1. The three config layers

  1. Plain env vars — os.environ/os.getenv, read directly. The vast majority of config (see §3).
  2. Starlette Config(".env") — flowfile_core/flowfile_core/configs/settings.py:129, config = Config(".env"). Reads the process's current working directory's .env file, with real env vars taking precedence over the file (Starlette semantics). Only 4 keys go through it: DEBUG, FILE_LOCATION, AVAILABLE_RAM, FLOWFILE_WORKER_URL (settings.py:130-133). Gotcha: which .env gets read depends entirely on the directory you launch flowfile_core from — not the repo root, not the package dir.
  3. Runtime-mutable flags (MutableBool, flowfile_core/flowfile_core/configs/utils.py) — an env var seeds the boot value, but an admin HTTP endpoint (or any Python call site) can flip .set(bool) live, process-wide, with zero restart. See §4.

2. FLOWFILE_MODE — semantics per value

Declared flowfile_core/flowfile_core/configs/settings.py:138: FLOWFILE_MODE = os.getenv("FLOWFILE_MODE", "electron"), with helpers is_docker_mode() / is_electron_mode() / is_package_mode() (settings.py:141-153).

Where the default gets stamped into os.environ (import-time side effect — four places):

  • flowfile_core/flowfile_core/__init__.py:12-13
  • flowfile_core/flowfile_core/configs/__init__.py:8-9
  • flowfile_core/flowfile_core/main.py:53-54
  • flowfile/flowfile/web/__init__.py:146-147 (inside start_server, i.e. flowfile run ui)
  • Tauri shell hard-sets it too: flowfile_frontend/src-tauri/src/env.rs:52 → FLOWFILE_MODE=electron
  • Docker bakes it: flowfile_core/Dockerfile:70, flowfile_worker/Dockerfile:62, docker-compose.yml:24,69 → FLOWFILE_MODE=docker

Caching split (load-bearing gotcha): settings.FLOWFILE_MODE is captured once, at import. Several other call sites re-read os.environ per call instead: auth/sharing.py:76 (sharing_enabled(), plus ambient_credentials_allowed() below it — the docker gate on cloud nodes, the storage browser and the cloud Delta routes — and uses_server_identity(), the admin-only gate on server-identity cloud connections built on it), shared/storage_config.py:26-28, kernel/manager.py:325, routes/file_manager.py:36, routes/secrets.py:97,139,180, auth/jwt.py:44,61,97,142,238, auth/secrets.py:19-25,180,210, flowfile_worker/secrets.py:131, database/init_db.py:55, flowfile/api.py:375. Changing the env var mid-process changes only the per-call group — settings.FLOWFILE_MODE-derived constants stay frozen at the import-time value.

ValueWho sets itWhat it gates
electron (default)unset → stamped at import; Tauri env.rsSingle-user desktop. local_user (id=1) auto-auth (auth/jwt.py:97-102); JWT secret auto-generated + persisted via SecureStorage (auth/jwt.py:61-66); master key auto-generated + stored (auth/secrets.py:210-224); FLOWFILE_INTERNAL_TOKEN auto-generated if absent and persisted via SecureStorage so CLI subprocesses match the server (auth/jwt.py); secrets routes force user_id=1 (routes/secrets.py:97); sharing routers 404 (sharing_enabled() false); file-manager routes 403 (routes/file_manager.py:36); storage under ~/.flowfile; user data = $HOME.
dockerDockerfiles / composeMulti-user. Startup fails without JWT_SECRET_KEY (auth/jwt.py:68-70); master key required via FLOWFILE_MASTER_KEY env or /run/secrets/flowfile_master_key (auth/secrets.py:140-169,210); FLOWFILE_INTERNAL_TOKEN required (auth/jwt.py:47-51); admin seeded from FLOWFILE_ADMIN_USER/_PASSWORD (database/init_db.py:55-65); storage /app/internal_storage + /data/user (compose overrides user data to /app/user_data); file manager + sharing enabled; /project router 404s unless FLOWFILE_ENABLE_PROJECTS truthy; ambient_credentials_allowed() is false, so cloud reader/writer nodes refuse "No connection" (the server's own credentials) and absolute local paths, and the storage browser / cloud Delta routes refuse ambient credentials; uses_server_identity() is true for aws-cli/env_vars/iam_role/managed_identity, so only admins may save such connections and only admin-owned ones resolve (full rule in §3.17's AWS_* note; package mode keeps all of it).
packageNothing in the repo sets this — an operator sets it manually (verified: only compose/Dockerfiles set docker; only import-time defaults set electron)is_package_mode() true; because it's ≠ electron, sharing is enabled, and JWT/master-key follow the non-electron path (JWT_SECRET_KEY required; SecureStorage path falls to SECURE_STORAGE_PATH default /tmp/.flowfile). Projects always on (routes/public.py:49).
tauri (fallback string, never actually set)routes/public.py:45: mode = os.environ.get("FLOWFILE_MODE", "tauri") — a different default string than everywhere elseUnreachable through normal startup because importing flowfile_core always stamps electron first. The frontend treats electron|tauri|desktop as synonyms (public.py:42-44 comment, env.rs:47-52). Don't "unify" this default — the comment explains the intent.

3. Master env-var table

Every variable read anywhere in package source, grouped as in the codebase. "Read at" is file:line in the current tree; re-verify with the greps in "Provenance" before trusting a line number across a refactor.

3.1 Mode / auth / secrets
VarRead atDefaultEffect
FLOWFILE_MODEsettings.py:138 (+ ~20 per-call sites, §2)electron (stamped at import)Runtime mode; gates auth/secrets/sharing/storage/file-manager (see §2 table).
JWT_SECRET_KEYauth/jwt.py:68none — raises in non-electron modeJWT signing secret.
FLOWFILE_MASTER_KEYauth/secrets.py:150; flowfile_worker/flowfile_worker/secrets.py:90none; falls back to Docker secret file /run/secrets/flowfile_master_key (auth/secrets.py:159); env wins; validated as a Fernet key, quotes strippedFernet master key encrypting all user secrets. Worker must be given the same key.
FLOWFILE_INTERNAL_TOKENauth/jwt.py:42; kernel/manager.py:1227; kernel_runtime/flowfile_client.py:243auto-generated and persisted via SecureStorage in electron (auth/jwt.py, internal_token entry, written back to os.environ), so CLI subprocess runs agree with the server; raises otherwiseX-Internal-Token header for kernel→core service auth.
FLOWFILE_INTERNAL_SERVICE_USER_IDauth/jwt.py:3181User id attributed to the _internal_service principal when a kernel's owner can't be resolved.
FLOWFILE_ADMIN_USER / FLOWFILE_ADMIN_PASSWORDdatabase/init_db.py:58-59none → warning, no admin createdSeeds the initial admin account. Docker-only guard at init_db.py:55.
SECURE_STORAGE_PATHauth/secrets.py:25/tmp/.flowfileSecureStorage dir for non-electron modes (Fernet-encrypted JSON + .secret_key).
FLOWFILE_SECURE_STORAGE_PATHauth/secrets.py (electron branch); flowfile_worker/secrets.pyunset → $APPDATA/flowfile or ~/.config/flowfileRelocates the SecureStorage dir (jwt_secret / master_key / internal_token). Set by the core and frame conftests. Core and worker must resolve it identically — core encrypts $ffsec$ secrets with the master key found there and the worker re-derives it, so a split store fails every worker-offloaded secret decrypt. Test/dev knob; not in .env.example or the deployment docs.
APPDATAauth/secrets.py:22; flowfile_worker/secrets.py:31~/.config fallbackWindows app-data root for electron SecureStorage (<APPDATA>/flowfile). OS var, not Flowfile-specific.
3.2 Ports & service discovery
VarRead atDefaultEffect
FLOWFILE_WORKER_PORTsettings.py:105,12563579 (DEFAULT_WORKER_PORT, settings.py:16); CLI --worker-port winsPort core dials the worker on.
WORKER_HOSTsettings.py:102,1270.0.0.0 (non-Windows) / 127.0.0.1 (Windows)Host core dials the worker on. Compose sets flowfile-worker (compose:35); Tauri sets 127.0.0.1 (env.rs:72).
FLOWFILE_WORKER_URLsettings.py:133 (Starlette Config: env or CWD .env)get_default_worker_url(WORKER_PORT) — http://{WORKER_HOST}:{port} + /worker suffix iff SINGLE_FILE_MODEFull worker URL override; consumed as WORKER_URL throughout flow_data_engine/subprocess_operations/subprocess_operations.py.
CORE_HOST / CORE_PORTflowfile_worker/flowfile_worker/configs.py:16-170.0.0.0/127.0.0.1(Win), 63578Where the worker (and its spawned children) call core back. Compose sets CORE_HOST=flowfile-core (compose:70); Tauri sets both (env.rs:68-69).
FLOWFILE_HOST / FLOWFILE_PORTflowfile/flowfile/api.py:22-23127.0.0.1 / 63578Where the flowfile CLI/api client probes and spawns core.
FLOWFILE_MODULE_NAMEflowfile/flowfile/api.py:25flowfileModule the CLI launches as server.
FORCE_POETRY / POETRY_PATH / POETRY_ACTIVE / VIRTUAL_ENVflowfile/flowfile/api.py:26-27,103-106empty / poetry / empty / emptyHow flowfile.api decides to spawn the server via Poetry vs a venv Python (dev only).
CLI argssettings.py:71-83 parse_args (--host --port --worker-port); flowfile_worker/configs.py:23-45 (--host --port --core-host --core-port)server 0.0.0.0:63578; worker 63579Args win over env vars.

Non-env port facts: Tauri scans a free (core, worker) port pair starting at 63578 (src-tauri/src/sidecar/mod.rs:66-77,118-136) and injects window.__FLOWFILE_PORTS__ for the renderer. Kernel containers get host ports 19000-19999 (kernel/manager.py, _BASE_PORT=19000, _PORT_RANGE=1000); container-internal port is always 9999 (kernel_runtime/Dockerfile EXPOSE 9999).

3.3 Runtime feature flags (MutableBool — see §4)
VarRead atDefaultTruthy parseEffect
FLOWFILE_SINGLE_FILE_MODEsettings.py:19; flowfile/web/__init__.py:72-73"0"exact "1" onlyWorker routes co-hosted on core under /worker; worker URL gets a /worker suffix.
FLOWFILE_OFFLOAD_TO_WORKERsettings.py:22"1"exact "1" onlyHeavy compute routed to the worker; off = in-core execution (violates the "core never collects" contract if you rely on it for large data — see flowfile-architecture-contract).
FEATURE_FLAG_AIsettings.py:25-27ontrue/1/yes/on (case/space-insensitive)Master gate for the entire /ai/* router (503 when off).
FLOWFILE_LSP_ENABLEDsettings.py:32-34ontrue/1/yes/onNotebook Jedi/LSP bridge; off ⇒ /lsp/* degrades to empty 200 (never 503) so editors silently fall back to client-side completion.
FLOWFILE_AI_LOG_PROMPTSsettings.py:37-39offtrue/1/yes/onAppends a JSONL line per LLM call to <base>/ai_prompts/YYYY-MM-DD.jsonl.
FLOWFILE_AI_LOG_PROMPTS_SCRUBsettings.py:42-44offtrue/1/yes/onPII-scrubs user/tool messages in the prompt log (system + assistant stay verbatim).
FLOWFILE_ENABLE_PROJECTSsettings.py:49-51off (env default); compose defaults true (compose:34)true/1/yes/onEnables the /project/* git-tracking router in docker mode (404 when off); always on outside docker (public.py:49).
FLOWFILE_SCHEDULER_ENABLEDflowfile_core/flowfile_core/main.py:73off; compose sets true (compose:32)true/1/yes — NO on (differs from all the others above!)Auto-starts the embedded FlowScheduler in core's lifespan.
3.4 Storage & database
VarRead atDefaultEffect
FLOWFILE_STORAGE_DIRshared/storage_config.py:44 (docker), :46 (local)docker /app/internal_storage; local ~/.flowfileInternal root (base_directory): cache, temp, logs, DB, template_data. Tauri env.rs:44 sets it to ~/.flowfile explicitly.
FLOWFILE_USER_DATA_DIRshared/storage_config.py:59docker /data/user; local $HOMEUser-data root: flows, uploads, outputs, catalog_tables, notebooks. Setting this locally does nothing — local path is always Path.home(), env only honored in docker mode. Compose overrides to /app/user_data.
FLOWFILE_SHARED_DIRshared/storage_config.py:157,171,243<base>/temp/kernel_sharedCore↔worker↔kernel exchange dir + global_artifacts/artifact_staging subpaths. Must stay Docker-visible — don't relocate under base_directory for Docker deployments.
FLOWFILE_DB_PATHshared/storage_config.py:410,427noneExplicit SQLite path override; wins over TESTING; also disables legacy-DB migration lookup.
FLOWFILE_DB_BACKUP_KEEPflowfile_core/database/backup.py::keep_count (per call)10Snapshots kept in db_backups/; <= 0 disables every snapshot (pre-migration, pre-update, manual — one shared budget; POST /system/db_backups answers 409 BACKUPS_DISABLED); unparseable → warn + 10.
TESTINGshared/storage_config.py (get_database_url, logs_directory)none; flowfile_core/tests/conftest.py:23 sets 'True'== "True" ⇒ DB becomes <base>/temp/test_flowfile_catalog.db — one shared file per machine; concurrent pytest sessions clobber each other's teardown. Isolate with FLOWFILE_DB_PATH per session. Also redirects logs_directory to <base>/temp/test_logs so suites never write into or expire the developer's real logs.
FLOWFILE_SKIP_STARTUP_MIGRATIONflowfile_core/flowfile_core/database/init_db.py:26unsetAny value ⇒ skip the Alembic startup migration on import. Needed for diagnostics — importing flowfile_core otherwise migrates the live catalog DB.
FLOWFILE_DB_READ_HEDGE_DELAYshared/db_reader.py:258 (seconds, float)Delay before a hedged SQLAlchemy read races connectorx.
FLOWFILE_RUN_LOG_RETENTION_DAYSshared/run_logs.py:_retention_days (read per call)30Age cutoff for the scheduled_run_*.log / flow_*.log sweep in cleanup_old_logs(), run at core startup and on the throttled scheduler tick (LOG_SWEEP_INTERVAL, 1 h). 0 or negative disables retention; an unparseable value warns and falls back to 30.
TEMP_DIR (env var, distinct from the TEMP_DIR module constant)settings.py:88 (get_temp_dir())tempfile.gettempdir()DEAD. get_temp_dir() has zero callers repo-wide. The unrelated TEMP_DIR module constant (settings.py:134) is storage.temp_directory.
3.5 Catalog object storage
VarRead atDefaultEffect
FLOWFILE_CATALOG_STORAGE_URIsettings.py:54-60 (read per call, not cached)noneCreation-time default storage root (e.g. s3://bucket/catalog) for new catalog tables. Not a live override — the seeded "General" catalog stays local even if you set this later.
FLOWFILE_CATALOG_STORAGE_CONNECTIONsettings.py:63-68 (per call)noneName of an existing CloudStorageConnection supplying credentials; required when the URI above is set.
3.6 AI subsystem
VarRead atDefaultEffect
FLOWFILE_AI_<PROVIDER>_RPM / _RPDai/scheduler.py:296-297 templates + .upper() (:324); parsed by _read_int_env (:244-263 — non-int or ≤0 logged + ignored)unset = no enforcementSoft per-provider request budget, per worker process (in-memory deque). Providers: ANTHROPIC OPENAI GOOGLE GROQ OPENROUTER; ollama is unlimited (_UNLIMITED_PROVIDERS, scheduler.py:268).
ANTHROPIC_API_KEY, OPENAI_API_KEY, GEMINI_API_KEY/GOOGLE_API_KEY, GROQ_API_KEY, OPENROUTER_API_KEYai/byok.py:52-63 map, :85 detect_env_fallback; litellm also reads them itselfunsetProvider fallback when no BYOK credential row is saved for that user.
LITELLM_LOCAL_MODEL_COST_MAPai/__init__.py:31 (os.environ.setdefault(...), a write, before any lazy litellm import)"True"Keeps litellm from fetching its cost map over the network at import time.
FLOWFILE_LOCAL_MODEL_CTXai/local_model/manager.py:11016384First-run seed only for the local llama.cpp context window; a UI-persisted sidecar file wins after the first run. Clamped 2048-32768 (:113-114).
3.7 Kernel orchestration (core side)
VarRead atDefaultEffect
FLOWFILE_KERNEL_IMAGEkernel/manager.py:64-68 via _envvar_or_default (:48-55 — empty string counts as unset, deliberately, because compose writes ${VAR:-} as "")_KERNEL_IMAGE_BASE_DEFAULT in kernel/images.pyLegacy/base-flavour image override; read at lookup time, not import.
FLOWFILE_KERNEL_IMAGE_BASE / _ML / _LITE / _NOTEBOOKkernel/images.pyper-flavour defaults in kernel/images.py (the notebook tag is the app version)Per-flavour pins; _BASE wins over the legacy FLOWFILE_KERNEL_IMAGE.
FLOWFILE_DOCKER_NETWORKmanager.py:393auto-detected (_detect_docker_network)Docker-in-Docker network that kernel containers join.
FLOWFILE_CORE_URLmanager.py:1216 (core writes it into the kernel's env); kernel_runtime/flowfile_client.py:219 (kernel reads it)DinD: http://flowfile-core:63578; local: http://host.docker.internal:63578How a kernel container dials core back.
3.8 Canvas notebook (core side)

None. Core runs no notebook process, and main.py installs the one clean-run runner at import (notebook/runner.py::install_notebook_runner); no env var switches it.

3.9 Kernel-container contract vars (set by core in _build_kernel_env, manager.py:1200-1258; read inside kernel_runtime)

These are container-internal contract vars — an operator normally never sets them by hand; core sets them per-kernel at launch.

VarSet at (core)Read at (kernel)Kernel-side defaultEffect
KERNEL_PACKAGESmanager.py:1208 (always "" — packages are pre-baked into the derived image)kernel_runtime/entrypoint.sh""pip-install loop at container boot (constraints-pinned).
KERNEL_CONSTRAINTS_FILEDockerfile ENV, kernel_runtime/Dockerfile:84entrypoint.sh/opt/constraints.txtpip constraint file for entrypoint installs.
FLOWFILE_CORE_URLmanager.py:1210-1217flowfile_client.py:219http://host.docker.internal:63578Core API endpoint.
FLOWFILE_INTERNAL_TOKENmanager.py:1219-1230 (prefers get_internal_token(), persisted in electron)flowfile_client.py:243 (fallback; per-request ctx token preferred)noneX-Internal-Token header. KernelManager.execute_sync stamps request.internal_token on every execute, so the baked env value is a dead fallback on core-driven paths (this is what heals adopted stale-token containers).
FLOWFILE_KERNEL_IDmanager.py:1232flowfile_client.py:248,339noneX-Kernel-Id lineage/ownership header.
FLOWFILE_HOST_SHARED_DIRmanager.py:1238-1239 (only when bind-mounted, i.e. NOT named-volume DinD)flowfile_client.py:58unsetHost→container path translation for the shared dir.
FLOWFILE_KERNEL_SHARED_DIRmanager.py:1243flowfile_client.py:598/sharedShared-dir path as seen inside the container.
FLOWFILE_HOST_CATALOG_TABLES_DIRmanager.py:1250-1251 (local mode only)flowfile_client.py:52,999unsetHost catalog-tables path for translation.
FLOWFILE_KERNEL_CATALOG_TABLES_DIRmanager.py:1252flowfile_client.py:989/catalog_tablesIn-container catalog-tables mount.
KERNEL_IDmanager.py:1253kernel_runtime/main.py:200defaultPersistence sub-path key.
PERSISTENCE_ENABLEDmanager.py:1254main.py:198true (parses 1/true/yes)Artifact persistence on/off.
PERSISTENCE_PATHmanager.py:1255main.py:199/shared/artifactsArtifact persistence root.
RECOVERY_MODEmanager.py:1256 (kernel.recovery_mode.value)main.py:201lazy (enum lazy|eager|clear; clear is destructive)Artifact recovery behavior at boot.
PERSISTENCE_CLEANUP_HOURSnot set by core (kernel default only)main.py:20324 (float; 0 disables)Startup GC of old artifacts.
MAX_NAMESPACESnot set by coremain.py:7620LRU cap on per-flow notebook namespaces.
MAX_DISPLAY_OUTPUTSnot set by coremain.py:82200LRU cap on stored display outputs.
FLOWFILE_SHARED_PATHnobody sets itflowfile_client.py:221 (_SHARED_PATH)/sharedDEAD — assigned once into a module var, never read again.
3.10 Public flow-API tunables
VarRead atDefaultEffect
FLOWFILE_API_RUN_TIMEOUT_SECONDSflowfile_core/flowfile_core/routes/flow_api.py:51120 (float)Timeout for one public-API-triggered flow run.
FLOWFILE_API_MAX_CONCURRENT_RUNSroutes/flow_api.py:574 (int → asyncio.Semaphore)Global cap on concurrent public-API runs; beyond cap ⇒ fast 503.
3.11 Global-artifact storage backend
VarRead atDefaultEffect
FLOWFILE_ARTIFACT_STORAGEflowfile_core/flowfile_core/artifacts/__init__.py:64filesystems3 switches to a presigned-URL S3Storage (shared/artifact_storage.py).
FLOWFILE_S3_BUCKETartifacts/__init__.py:69none — raises ValueError when backend is s3 and this is unsetS3 bucket name.
FLOWFILE_S3_PREFIXartifacts/__init__.py:75global_artifacts/Key prefix.
FLOWFILE_S3_REGIONartifacts/__init__.py:76us-east-1Region.
FLOWFILE_S3_ENDPOINT_URLartifacts/__init__.py:77noneCustom endpoint (MinIO etc.).
3.12 Project git-tracking secret placeholders
VarRead atEffect
FLOWFILE_SECRET_<NAME>flowfile_core/flowfile_core/project/secrets_resolver.py:24-26 (env_key: FLOWFILE_SECRET_ + name uppercased, non-alnum runs → _), :44-48 (resolve: env var wins over the project's .env)Supplies values for ${secret:NAME} placeholders when importing a git project. Project-root .env (untracked) is the fallback.
3.13 Google OAuth (GA connections)
VarRead atDefaultEffect
GOOGLE_OAUTH_CLIENT_ID / GOOGLE_OAUTH_CLIENT_SECRETsettings.py:163-164""Fallback OAuth app credentials when no per-user DB secret row exists (configs/app_settings.py:69-70: get_user_secret(...) or GOOGLE_OAUTH_CLIENT_ID).
GOOGLE_OAUTH_REDIRECT_URIsettings.py:165-168http://localhost:{SERVER_PORT}/ga_connections/oauth/callbackOAuth redirect fallback.
3.14 Sidecar / desktop shell (Rust — vars written for the Python children)

build_child_env(core_port, worker_port) in flowfile_frontend/src-tauri/src/env.rs:10-96 starts from the shell's environment and overrides: HOME, TMPDIR, DOCKER_CONFIG (=~/.docker), FLOWFILE_STORAGE_DIR (=~/.flowfile, pre-creating cache/temp/logs/system_logs/flows/database subdirs), FLOWFILE_MODE=electron (env.rs:52), FLOWFILE_SUPERVISOR_PID (=shell PID, env.rs:58-61), FLOWFILE_WORKER_PORT, CORE_PORT, CORE_HOST=127.0.0.1, WORKER_HOST=127.0.0.1 (env.rs:67-72), DOCKER_HOST (npipe:////./pipe/docker_engine on Windows else unix:///var/run/docker.sock, env.rs:74-84), and prepends /usr/local/bin:... to PATH on Unix.

VarRead atEffect
FLOWFILE_SUPERVISOR_PIDshared/parent_watcher.py:32Presence-gated: enables a parent-death watcher thread in sidecars (polls os.getppid() every 1s; exits when reparented). Never set for CLI/Docker runs, so the watcher never fires there.
FLOWFILE_TARGET_TRIPLEcompile-time env!() in src-tauri/src/sidecar/mod.rs:162, emitted by build.rs:8 cargo:rustc-envPicks the binaries/<name>-<triple> sidecar filename.
3.15 Frontend / WASM build & test-time (not backend config)
VarRead atEffect
NODE_ENVsrc/renderer/config/environment.ts:12-18; .eslintrc.js:29-30Derives ENV.isDevelopment/enableDevTools/...; compose frontend sets NODE_ENV=production (compose:11).
import.meta.env.MODE / BASE_URL / DEVDocumentationView.vue:15; router/index.ts:149; stores/update-store.ts:71 (skips the launch update check in dev)Dev-mode doc links, hash-router base.
CIplaywright.config.ts:9-10Retries/forbidOnly in E2E.
TEST_URL / API_URLtests/web-flow.spec.ts:23-24; tests/canvas-overlays.spec.ts:20-21; tests/helpers/api.ts:5-6Playwright targets; the Makefile sets TEST_URL=http://localhost:4173 for make test_e2e.
E2E_RUN_IDtests/cloud-storage-flow.spec.ts:41MinIO prefix (s3://flowfile-test/cloud-e2e-<id>/) and connection-name suffix; defaults to a timestamp. make test_e2e_cloud sets it and deletes the prefix afterwards.
E2E_AWS_PROFILE_CONFIGUREDtests/cloud-storage-flow.spec.ts:46 (=== "1")Enables the "No connection" cloud test, which needs the servers started with a MinIO-only AWS profile; make test_e2e_cloud and e2e-tests.yml set it.
PLAYWRIGHT_HTML_OPENPlaywright itselfThe Makefile E2E targets set never so a failure does not block on the HTML report server.
BUILD_MODEflowfile_wasm/vite.config.ts:5 ('lib')WASM lib-vs-app build; set by package.json build:lib.
npm_package_versionflowfile_wasm/vite.config.ts:6Injected app version.
3.16 Starlette-Config keys (settings.py:129-133 — env var OR .env in the process CWD)
KeyDefaultStatus
DEBUGFalseDEAD — no consumer outside settings.py.
FILE_LOCATION".\\files\\"DEAD — no consumer.
AVAILABLE_RAM8 (GB, int)Live — flow_data_engine/utils.py:40 uses it to decide if an estimated frame fits in memory.
FLOWFILE_WORKER_URLcomputed worker URLLive — see §3.2.
Show full SKILL.md (1,879 more words)Show less
3.17 Test-infrastructure env (not runtime config, but easy to confuse with the above)
  • TEST_MODE — flowfile_worker/configs.py:18: presence-based ("TEST_MODE" in os.environ) — TEST_MODE=0 still enables it! Effect: flowfile_worker/secrets.py:128 returns a static test master key instead of real key resolution. CI sets it in .github/workflows/test-kafka-integration.yml:115 and test-kernel-integration.yml:72.
  • TESTING='True' — set by flowfile_core/tests/conftest.py:23; see §3.4 for the shared-DB hazard.
  • FLOWFILE_WORKER_HOST (conftest.py:53, default 0.0.0.0), FLOWFILE_STARTUP_TIMEOUT (:56, 30s), FLOWFILE_SHUTDOWN_TIMEOUT (:58, 15s), SKIP_WORKER_TESTS (:226, == "1"), FLOWFILE_TEST_REUSE_WORKER (conftest.py::_claim_worker_port, == "1": reuse a worker already on the default 63579 instead of moving the session to a free port; an explicit FLOWFILE_WORKER_PORT is always used as given) — test-only. FLOWFILE_WORKER_HOST is NOT read by package source (which uses WORKER_HOST) — near-identical name, different variable, easy to set the wrong one.
  • test_utils/ Docker fixtures: TEST_POSTGRES_{HOST,PORT,USER,PASSWORD,DB,SCHEMA,IMAGE,CONTAINER,STARTUP_TIMEOUT,SHUTDOWN_TIMEOUT}, TEST_MYSQL_* (same shape + ROOT_PASSWORD), TEST_MINIO_{HOST,PORT,CONSOLE_PORT,ACCESS_KEY,SECRET_KEY,CONTAINER}, TEST_GCS_{HOST,PORT,CONTAINER}, TEST_AZURITE_{HOST,BLOB_PORT,CONTAINER}, TEST_REDPANDA_{HOST,PORT,IMAGE,CONTAINER}, KEEP_{MINIO,GCS,AZURITE,REDPANDA}_RUNNING, CI, GITHUB_ACTIONS.
  • Tests also export AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY/AWS_ENDPOINT_URL/AWS_REGION/AWS_ALLOW_HTTP/AWS_SESSION_TOKEN for object-store SDKs. Package source never reads AWS_* itself, but the ambient AWS environment is still live runtime config: a cloud node with No connection, a saved aws-cli connection with a blank aws_profile, and any env_vars connection resolve credentials through boto3's default chain and object_store's own env lookup, so AWS_* in the core/worker environment (AWS_PROFILE, AWS_SHARED_CREDENTIALS_FILE, AWS_CONFIG_FILE, AWS_ENDPOINT_URL, AWS_ALLOW_HTTP, …) decides where such a node reads and writes (a saved connection's own endpoint_url still wins). Docker mode (auth/sharing.py, read live): the no-connection fallback is refused for every user, admins included (ambient_credentials_allowed() → flow_graph.get_cloud_connection_settings raises ValueError("Select a cloud storage connection; …")); server-identity connections (SERVER_IDENTITY_AUTH_METHODS = aws-cli, env_vars, iam_role, managed_identity; uses_server_identity()) are admin-only — a non-admin create/update is a 422 in routes/cloud_connections.py, and db_connections.get_cloud_connection_schema raises CloudConnectionNotAllowedError for any such row whose owner is not an admin (nodes, storage browser + cloud Delta routes as 400 CONNECTION_NOT_ALLOWED, catalog storage), so admin-owned ones keep working, group-shared included; cloud node paths must be cloud URIs (shared/cloud_storage/utils.py::validate_cloud_resource_path: empty/relative refused in every mode, absolute local paths refused in docker). Suites that exercise it pin a temp static-key profile plus AWS_ENDPOINT_URL=http://localhost:9000, AWS_ALLOW_HTTP=true and AWS_EC2_METADATA_DISABLED=true, so nothing can reach real AWS.
3.18 CI-only runtime env (across all 12 workflows — only 3 hits)

TEST_MODE: "1" (kafka + kernel integration workflows); FLOWFILE_INTERNAL_TOKEN: ${{ github.run_id }}-test-token (test-kernel-integration.yml:74); FLOWFILE_KERNEL_IMAGE: flowfile-kernel-base:test (test-kernel-integration.yml:76).

3.19 Interpreter hygiene (Dockerfiles, not app config)

PYTHONPATH=/app, PYTHONDONTWRITEBYTECODE=1, PYTHONUNBUFFERED=1 in flowfile_core/Dockerfile:69-72, flowfile_worker/Dockerfile:61-64, kernel_runtime/Dockerfile:80-84 (+ docker-compose.yml:46-47,75-76).


4. MutableBool — flipping a feature flag without restart

flowfile_core/flowfile_core/configs/utils.py defines MutableBool: a dataclass wrapping value: bool with __bool__, &/| combinators, int/float coercion, and .set(value). settings.py exports six instances: SINGLE_FILE_MODE, OFFLOAD_TO_WORKER, FEATURE_FLAG_AI, FLOWFILE_LSP_ENABLED, FLOWFILE_AI_LOG_PROMPTS, FLOWFILE_AI_LOG_PROMPTS_SCRUB. Every call site does bool(_settings.FEATURE_FLAG_AI) at call time, so .set() takes effect immediately, process-wide, with no reload — but only in that process (see caveat below).

FEATURE_FLAG_AI live flip:

  • Gate: flowfile_core/flowfile_core/ai/feature_flag.py — is_ai_enabled() reads the MutableBool per call; require_ai_enabled() is a router-level Depends raising 503 with "AI features are disabled. Set FEATURE_FLAG_AI=true to enable.".
  • Flip: POST /system/feature_flags/ai (ai/admin_routes.py:58-78, admin-only, mounted under /system — deliberately outside the gated /ai router so it stays callable while the gate is off). Sets both settings.FEATURE_FLAG_AI.set(enabled) and os.environ["FEATURE_FLAG_AI"] (admin_routes.py:76-77). Response always has persisted: false — surviving a restart is the operator's .env's job, not this endpoint's. GET /system/feature_flags/ai reads current state (also admin-only).

FLOWFILE_LSP_ENABLED live flip: identical pattern in flowfile_core/flowfile_core/lsp/admin_routes.py — POST/GET /system/feature_flags/lsp (admin_routes.py:49,60). Difference: /lsp/* never 503s when off — it degrades to empty-200 so the editor falls back to client-side completion. Caveat in the module docstring: open editor sessions cache /lsp/capabilities per session, so a live flip only reaches them on reload.

Other live-mutable state (not admin-endpoint-backed):

  • OFFLOAD_TO_WORKER.set(False) is forced by python -m flowfile_core.main --run-flow (per flowfile_core/CLAUDE.md), and flowfile/web/__init__.py:157 sets OFFLOAD_TO_WORKER.value = True in unified (pip) mode.
  • import flowfile mutates os.environ unconditionally: flowfile/flowfile/__init__.py:17-18 sets FLOWFILE_WORKER_PORT=63578 and FLOWFILE_SINGLE_FILE_MODE=1 at import time, before any of your code runs. This is how the pip-installed unified mode co-hosts the worker on the core port. Consequence: any process that does import flowfile (even just to reach flowfile_frame) silently flips core into single-file mode if flowfile_core.configs.settings is imported afterward. Import order matters.

Multi-process caveat: in a multi-worker deployment (e.g. gunicorn -w N), a flip via HTTP hits one worker process only (inferred from the per-process nature of MutableBool; .env.example documents the identical caveat for AI rate limits — §3.6, per-process in-memory deques).


5. Parsing quirks — truthy rules are NOT uniform

This is the single most common source of "I set the var and nothing changed" bugs. There are five different truthy rules in play:

RuleApplies to
true/1/yes/on (case/whitespace-insensitive)FEATURE_FLAG_AI, FLOWFILE_LSP_ENABLED, FLOWFILE_AI_LOG_PROMPTS, FLOWFILE_AI_LOG_PROMPTS_SCRUB, FLOWFILE_ENABLE_PROJECTS
true/1/yes — no onFLOWFILE_SCHEDULER_ENABLED — FLOWFILE_SCHEDULER_ENABLED=on silently does nothing.
exact string "1" onlyFLOWFILE_SINGLE_FILE_MODE, FLOWFILE_OFFLOAD_TO_WORKER — =true or =yes silently does nothing.
presence-only (value ignored)TEST_MODE (TEST_MODE=0 still enables it!), FLOWFILE_SKIP_STARTUP_MIGRATION, FLOWFILE_SUPERVISOR_PID.
exact string "True" (capitalized)TESTING — TESTING=true (lowercase) does not match == "True".

Corollary gotchas:

  • _envvar_or_default (kernel image vars, manager.py:48-55) treats an empty string as unset, deliberately, because Compose's ${VAR:-} interpolation writes "" for an unset host var. Don't "fix" this to treat "" as a real override.
  • AVAILABLE_RAM, DEBUG go through Starlette's cast=bool/cast=int, not the hand-rolled truthy checks above — different failure mode (raises on unparseable input rather than silently falling to default).

6. Drift report (both directions)

Documented but missing or stale
  1. .env.example:57 calls the /project router "admin-only" in docker mode — unverified nuance (the router-level permission dependency itself is out of this skill's scope); treat as a flag, not a confirmed fact.
Read in code but dead
  1. TEMP_DIR env var — settings.get_temp_dir() (settings.py:86-92) has zero callers repo-wide.
  2. FLOWFILE_SHARED_PATH — kernel_runtime/flowfile_client.py:221 assigns _SHARED_PATH; never referenced again.
  3. DEBUG and FILE_LOCATION Starlette-Config keys — read into module constants with zero consumers.
Read in code but absent from BOTH .env.example and root CLAUDE.md

FLOWFILE_LSP_ENABLED (+ its admin flip endpoint) · FLOWFILE_API_RUN_TIMEOUT_SECONDS · FLOWFILE_API_MAX_CONCURRENT_RUNS · FLOWFILE_ARTIFACT_STORAGE / FLOWFILE_S3_BUCKET / _PREFIX / _REGION / _ENDPOINT_URL · FLOWFILE_LOCAL_MODEL_CTX · FLOWFILE_DB_READ_HEDGE_DELAY · FLOWFILE_DOCKER_NETWORK · TESTING / FLOWFILE_SKIP_STARTUP_MIGRATION · FLOWFILE_HOST / FLOWFILE_PORT / FLOWFILE_MODULE_NAME / FORCE_POETRY / POETRY_PATH · SECURE_STORAGE_PATH · GOOGLE_OAUTH_CLIENT_ID / _CLIENT_SECRET / _REDIRECT_URI · FLOWFILE_SECRET_* placeholder prefix · AVAILABLE_RAM (Starlette key, live) · FLOWFILE_INTERNAL_SERVICE_USER_ID (documented only in docs/for-developers/kernel-architecture.md) · most of the kernel-container contract vars in §3.9 (PERSISTENCE_*, RECOVERY_MODE, KERNEL_ID, MAX_NAMESPACES, MAX_DISPLAY_OUTPUTS, KERNEL_PACKAGES, KERNEL_CONSTRAINTS_FILE, the FLOWFILE_HOST_*/FLOWFILE_KERNEL_* path-translation quartet — some appear in docs/for-developers/kernel-architecture.md, most don't anywhere).

.env.example ↔ docker-compose.yml divergences (trap-shaped, not bugs)
  • .env.example has no FLOWFILE_SCHEDULER_ENABLED line at all; compose hard-codes true; docs/users/deployment/docker.md says default is false. Net effect: local/pip runs never start the scheduler unless you set it yourself; a fresh .env copied from .env.example for a non-compose docker run also won't start it.
  • FLOWFILE_ENABLE_PROJECTS: env-level code default is off (settings.py:50), but compose defaults it on (compose:34) and .env.example:62 ships true. Read the compose file, not just the code default, before assuming projects are off.
  • Compose passes empty strings for unset kernel-image vars (${VAR:-}). This is safe only because _envvar_or_default treats empty as unset (§5) — copying that ${VAR:-} pattern for a var that does NOT special-case empty (e.g. FLOWFILE_MASTER_KEY, compose:31) yields an empty-string env that the consuming code must handle explicitly (it does, via a falsy check in secrets.py, but this is not free — verify before reusing the pattern for a new var).

7. Add-a-config-axis checklist

When you add a new environment-variable-driven behavior:

  1. Read it in exactly one place if possible. If it must be read per-call (like sharing_enabled() or the catalog-storage getters), say so in a comment — the import-time-vs-per-call split is the #1 source of "I set it but nothing changed" bugs in this codebase (§2, §6).
  2. Pick a truthy rule deliberately and be consistent with a sibling flag, not with "whatever felt natural." Prefer the true/1/yes/on rule used by the MutableBool flags (§3.3) unless you have a specific reason (e.g. FLOWFILE_SINGLE_FILE_MODE's exact-"1" rule exists to avoid ambiguity in a mode-switch, not by accident). Document the rule inline — this table exists because five different rules already crept in un-intentionally (§5).
  3. Give it a real default in code, and decide whether an empty string counts as "set" (compose's ${VAR:-} idiom means it usually shouldn't — mirror _envvar_or_default, manager.py:48-55, if the var can be Compose-templated).
  4. Add a line to .env.example (repo root, the only one in the repo) with a one-line comment; if the semantics are non-obvious (like FLOWFILE_CATALOG_STORAGE_URI's creation-time-only caveat), write the caveat there, not just in code.
  5. Add it to root CLAUDE.md's Environment Variables table if it's operator-facing; if it's a container-internal contract var like the ones in §3.9, a one-line mention in docs/for-developers/kernel-architecture.md is enough — don't bloat the root table with vars nobody sets by hand.
  6. Wire it into docker-compose.yml if docker deployments need a non-default value, and make sure the compose default doesn't silently diverge from the code default (§6 has three live examples of exactly this drift — don't add a fourth).
  7. Add or extend a test that asserts the default behavior AND at least one non-default value takes effect. If the var is read in the worker or a kernel container, a subprocess/container-level test (not just a unit test of the getter) is the only way to catch the "set at core, but the string mismatches at the read site" class of bug.
  8. If it's a live-flippable flag, follow the MutableBool pattern (§4): mount the admin endpoint under /system, not the feature's own gated router, set both the MutableBool and os.environ, and return persisted: false honestly — do not silently write back to a .env file.
  9. Decide whether the frontend needs to know (maintainer guidance, 2026-07-03: many config axes must be frontend-accessible — plan the exposure path when you add the var, not after). The renderer cannot read backend env: in Docker it is static files behind nginx, and import.meta.env is baked at build time — fine for build concerns, wrong for anything an operator sets at deploy time. If the var changes UI-visible behavior, expose it through a backend response and make the UI react. The two existing patterns to copy: the mode field the backend returns from FLOWFILE_MODE (consumed in flowfile_frontend/src/renderer/app/services/auth.service.ts), and AI availability signaled by the /ai/* 503 detail string (AI_DISABLED_DETAIL check in app/api/ai.api.ts). Never mint a VITE_* var for deployment config.

8. Quick reference: minimal env per deployment

  • Desktop (Tauri): nothing — env.rs supplies everything (mode, ports, storage, supervisor PID).
  • Local dev (poetry run flowfile_core + poetry run flowfile_worker): nothing required; defaults to electron mode, ~/.flowfile, ports 63578/63579. Optional: FLOWFILE_SCHEDULER_ENABLED=1 (note: the =on spelling silently does nothing, §5).
  • pip unified (flowfile run ui): nothing; import flowfile's side effect sets single-file mode; serves the UI at :63578/ui (host/port hard-checked to 127.0.0.1:63578, flowfile/web/__init__.py:154-157).
  • Docker: required JWT_SECRET_KEY, FLOWFILE_INTERNAL_TOKEN, FLOWFILE_MASTER_KEY (or the Docker secret file); recommended FLOWFILE_ADMIN_USER/_PASSWORD; compose wires WORKER_HOST, CORE_HOST, storage dirs, scheduler, projects, and kernel-image overrides for you — check compose defaults against §6 before assuming .env.example alone tells the whole story.

Classification rule (maintainer, 2026-07-03): split every var into installation-specific (paths, hosts, ports — defaulted per machine or wired by env.rs/compose) vs deployment config (secrets, tokens, mode, admin bootstrap, feature gates). Everything in the second group is required-or-relevant for hosting: a server deployment must consciously set them even though local/desktop runs never touch them. .env.example is the hosting operator's checklist — which is why the undocumented-var drift in §6 is a hosting hazard, not a docs nit.


Provenance and maintenance

All facts above were spot-verified by reading the cited files at their cited lines against the repo as of 2026-07-03 (v0.12.7), on a clean checkout. Re-run these before trusting any file:line in this document after a refactor:

bash
# Re-derive the full env-var read list (definitive checklist; compare unique names against §3)
grep -rhoE 'environ(\.get)?\[?\(? ?"[A-Z_0-9]+"|getenv\("[A-Z_0-9]+"' . --include="*.py" -r \
  | grep -oE '"[A-Z_0-9]+"' | tr -d '"' | sort -u

# Re-check every occurrence with file:line (use this to re-verify a specific var's line numbers)
grep -rn --include="*.py" -E "os\.environ|os\.getenv|environ\.get|getenv\(" . \
  --exclude-dir=node_modules --exclude-dir=target --exclude-dir=dist --exclude-dir=.venv --exclude-dir=.git

# TS/JS/Vue env reads (frontend + wasm)
grep -rn --include="*.ts" --include="*.js" --include="*.vue" --include="*.mjs" \
  -E "import\.meta\.env|process\.env" flowfile_frontend flowfile_wasm | grep -v node_modules

# Rust env reads (Tauri sidecar)
grep -rn -E "env::|std::env|option_env!|env!\(" flowfile_frontend/src-tauri/src

# FLOWFILE_MODE default-stamping sites (should be exactly 4 Python + 1 Rust + Dockerfiles/compose)
grep -rn 'FLOWFILE_MODE.*=.*"electron"\|FLOWFILE_MODE.*not in os.environ' \
  flowfile_core flowfile flowfile_frontend/src-tauri/src --include="*.py" --include="*.rs"

# MutableBool truthy-parse sites (confirms §3.3 / §5 truthy rules haven't drifted)
grep -n "MutableBool\|strip().lower() in" flowfile_core/flowfile_core/configs/settings.py

# Admin flip endpoints still mounted under /system, not under the gated router
grep -n "feature_flags" flowfile_core/flowfile_core/ai/admin_routes.py flowfile_core/flowfile_core/lsp/admin_routes.py

# Kernel image defaults + empty-string-is-unset guard
grep -n "_KERNEL_IMAGE.*DEFAULT\|_envvar_or_default" flowfile_core/flowfile_core/kernel/images.py

# Compose vs .env.example divergence re-check (scheduler / projects)
grep -n "FLOWFILE_SCHEDULER_ENABLED\|FLOWFILE_ENABLE_PROJECTS" docker-compose.yml .env.example

# Kernel image version doc-drift re-check
grep -n "flowfile-kernel-base:0\." flowfile_core/flowfile_core/kernel/images.py

If a grep above turns up a line-number shift but the same variable name and semantics, just fix the file:line in this document — don't re-litigate the fact. If a variable disappears entirely, move its row to a "removed" note rather than silently deleting history from this table (this is the config record for the whole monorepo; treat entries as append-mostly).

© Edwardvaneechoud, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

Just SKILL.md in .claude/skills/flowfile-config-and-flags of Edwardvaneechoud/Flowfile.

Open the folder on GitHubat commit 13aa287

Compare with similar skills

Flowfile Config and Flags Catalog next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Flowfile Config and Flags Catalog compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Flowfile Config and Flags Catalog this skillEdwardvaneechoud/Flowfile375—~12kAutomated safety check: NotesMIT
Burla Parallel Dev ClustersBurla-Cloud/burla263—~1.6kAutomated safety check: PassCustom licence
Zizkadb Dev SetupZIZKA-AI-SL/ZizkaDB125—~535Automated safety check: NotesCustom licence
Awf Debug Toolsgithub/gh-aw-firewall149—~2.6kAutomated safety check: NotesMIT
Burla Internals Deep DiveBurla-Cloud/burla263—~2.4kAutomated safety check: PassCustom licence
Code Reviewaide-family/moon253—~815Automated safety check: PassNone

Similar skills

  • Sets up an isolated Burla dev cluster per git worktree so several agents can work in parallel, and explains when to use local-dev or remote-dev.

    263 GitHub stars~1.6k tokensUpdated 16 days ago
    DevelopmentAuto-check passed
  • Zizkadb Dev Setup

    ZIZKA-AI-SL/ZizkaDB

    Set up and start the local ZizkaDB development stack. An agent skill from ZIZKA-AI-SL/ZizkaDB.

    125 GitHub stars~535 tokensUpdated 2 days ago
    DevelopmentAuto-check: notes
  • Awf Debug Tools

    github/gh-aw-firewall

    Official

    Practical Python scripts for debugging awf - parse logs, diagnose issues, inspect containers, test domains

    149 GitHub stars~2.6k tokensUpdated today
    DevelopmentAuto-check: notes
  • Burla Internals Deep Dive

    Burla-Cloud/burla

    Reference for Burla internals: how a remote_parallel_map job flows between services, how clusters and nodes are managed, and where the head keeps its state.

    263 GitHub stars~2.4k tokensUpdated 16 days ago
    DevelopmentAuto-check passed
  • Code Review

    aide-family/moon

    Reviews code for correctness and potential bugs, pinpoints bug locations by file and line, and suggests concrete fixes.

    253 GitHub stars~815 tokensUpdated 3 mo ago
    DevelopmentAuto-check passed
  • Dotnet Debugging

    novotnyllc/dotnet-artisan

    Debugs Windows and Linux/macOS applications (native, .NET/CLR, mixed-mode) with WinDbg MCP (crash dumps, !analyze, !syncblk, !dlk, !runaway, !dumpheap, !gcroot, BSOD), dotnet-dump, lldb with SOS…

    233 GitHub stars~2.1k tokensUpdated yesterday
    DevelopmentAuto-check passed

More from Edwardvaneechoud/Flowfile

All 19 skills in this repo
  • Flowfile AI Subsystem Guide

    Edwardvaneechoud/Flowfile

    Maps the /ai/ subsystem of flowfile_core, its three agent tiers, litellm seam, BYOK keys and rate limits, and sets rules for extending or debugging it safely.

    375 GitHub stars~7k tokensUpdated today
    Auto-check: notes
  • Flowfile Architecture Contract

    Edwardvaneechoud/Flowfile

    Maps Flowfile's core, worker, frontend, kernel, scheduler and shared services and the design contracts between them, for onboarding and cross-service debugging.

    375 GitHub stars~9.9k tokensUpdated today
    Auto-check passed
  • Flowfile Build and Environment Setup

    Edwardvaneechoud/Flowfile

    Recreates every Flowfile development and build environment from scratch, with exact version pins and an explanation of what each Makefile target really does.

    375 GitHub stars~7.3k tokensUpdated today
    Auto-check: notes
  • Flowfile Change Control

    Edwardvaneechoud/Flowfile

    Explains how changes to the Flowfile monorepo are gated, versioned and released, including version sync, stub and docs drift checks, Alembic migrations and pinned dependencies.

    375 GitHub stars~7.3k tokensUpdated today
    Auto-check passed
  • Flowfile Codegen Parity Campaign

    Edwardvaneechoud/Flowfile

    Runbook for closing gaps between a Flowfile visual flow's results and its exported Polars or FlowFrame Python code, measured by tests rather than by eye.

    375 GitHub stars~7.5k tokensUpdated today
    Auto-check passed
  • Flowfile Custom Node Authoring

    Edwardvaneechoud/Flowfile

    Turn a plain-English description ("a node that runs on the kernel and does XGBoost predictions", "a node that trims whitespace", "an ML clustering node") into a correct single-file Flowfile custom…

    375 GitHub stars~8.6k tokensUpdated today
    Auto-check passed

Works with

Questions about Flowfile Config and Flags Catalog

What does Flowfile Config and Flags Catalog do?

Catalog of Flowfile's environment variables and runtime flags: what each does, where the code reads it, its default, and where the docs disagree with the code. This skill is a catalog of how the Flowfile project is configured. Flowfile has no central config schema: about 90 environment variables are read ad hoc across six packages, plus a few runtime-mutable flags and four Starlette Config keys.

When should I use Flowfile Config and Flags Catalog?

Flowfile Config and Flags Catalog fits situations like: adding or changing an environment variable that Flowfile reads; debugging a config value that is not taking effect; writing a .env or docker-compose entry for Flowfile; auditing which FLOWFILE_ variables exist and where they are documented.

How do I install Flowfile Config and Flags Catalog in Claude Code?

Run `npx skills add Edwardvaneechoud/Flowfile --skill flowfile-config-and-flags -a claude-code`. Or copy the skill folder (.claude/skills/flowfile-config-and-flags in Edwardvaneechoud/Flowfile) into .claude/skills/flowfile-config-and-flags in your project. Claude Code loads it when a task matches its description.

How do I install Flowfile Config and Flags Catalog in Codex?

Run `npx skills add Edwardvaneechoud/Flowfile --skill flowfile-config-and-flags -a codex`. Or copy the skill folder (.claude/skills/flowfile-config-and-flags in Edwardvaneechoud/Flowfile) into .agents/skills/flowfile-config-and-flags in your project. Codex loads it when a task matches its description.

Can I use Flowfile Config and Flags Catalog in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add Edwardvaneechoud/Flowfile --skill flowfile-config-and-flags -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/flowfile-config-and-flags, .gemini/skills/flowfile-config-and-flags, .github/skills/flowfile-config-and-flags and .opencode/skills/flowfile-config-and-flags in your project.

What does Flowfile Config and Flags Catalog need to run?

Going by SKILL.md and its folder, Flowfile Config and Flags Catalog needs the command-line tools its instructions call (make, poetry, python and gunicorn) and credentials named FLOWFILE_INTERNAL_TOKEN, JWT_SECRET_KEY, FLOWFILE_MASTER_KEY and FLOWFILE_ADMIN_PASSWORD. Our summary lists: A checkout of the Flowfile repository.

Does Flowfile Config and Flags Catalog access the network?

SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.

Is Flowfile Config and Flags Catalog safe to install?

Our automated static check of SKILL.md found notes only (mentions a .env file), nothing it rates as a warning. It is not a guarantee. Review the folder before installing.

What licence does Flowfile Config and Flags Catalog use?

Flowfile Config and Flags Catalog is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Flowfile Config and Flags Catalog use?

About 12k tokens (SKILL.md is roughly 47k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Flowfile Config and Flags Catalog?

Skills that share tags, products or a category with Flowfile Config and Flags Catalog: Burla Parallel Dev Clusters (Burla-Cloud/burla, 263 stars), Zizkadb Dev Setup (ZIZKA-AI-SL/ZizkaDB, 125 stars), Awf Debug Tools (github/gh-aw-firewall, 149 stars) and Burla Internals Deep Dive (Burla-Cloud/burla, 263 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Flowfile Config and Flags Catalog?

Edwardvaneechoud (a GitHub user) maintains it in Edwardvaneechoud/Flowfile, which has 375 GitHub stars. The repository holds 19 skills in this directory. The repository was last updated on October 9, 2026.

Source: Edwardvaneechoud/Flowfile on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.