Configuration¶
Where keryx reads configuration from, in what order it wins, and what happens when a value is missing or wrong. The keys themselves are on the configuration keys page.
Which files keryx reads¶
Four files, in two scopes.
~/.keryx/config.yaml must exist before any command will run. Without it, every
command that does real work fails with:
failed to load configuration: no config file found hints="Run 'keryx init' to create a configuration."
keryx init writes it. The other three files are genuinely optional.
| File | Scope | Holds |
|---|---|---|
~/.keryx/config.yaml |
per user | tool settings, provider selection, defaults |
~/.keryx/themes.yaml |
per user | the style library (themes.*) |
~/.keryx/accounts.yaml |
per user | platform credentials, and nothing else |
.keryx.yaml |
per project | the project's own settings, committed with the repo |
The user directory is ~/.keryx — the home directory plus a dot and the tool name. It
is not ~/.config/keryx, and XDG_CONFIG_HOME does not move it.
The project file is discovered by walking up from the working directory, so keryx
run from anywhere inside the repo finds the same .keryx.yaml. This is what lets a
blog repo carry its own themes and provider choices while the machine-wide file holds
the API-independent preferences.
Which layer wins¶
Highest precedence first:
- Command-line flags you actually changed. A flag left at its default contributes nothing.
- The project
.keryx.yaml. ~/.keryx/accounts.yaml, then~/.keryx/themes.yaml, then~/.keryx/config.yaml.- Built-in defaults compiled into the binary.
The specialised user files outrank config.yaml deliberately. They are the canonical
homes for credentials and themes, and a stale value left behind in config.yaml must
not shadow the one that has been migrated out of it — which is what
auth migrate and
theme migrate do.
Merging is per key, not per file: a project file that sets only workspace.root still
inherits every theme from the user library.
Environment variables do not override config keys¶
There is no environment-variable layer. keryx sets no env prefix, and the
configuration store is built from files and flags only. Setting WORKSPACE_ROOT,
PROVIDERS_IMAGE or KERYX_PROVIDERS_IMAGE has no effect on any config key.
Environment variables are used, but only where a specific piece of code reads a
specific named variable — API keys, platform secrets, and the ffmpeg-wasi module
path. Those are enumerated on the environment variables page.
That list is exhaustive; anything not on it is not read.
What happens when a value is wrong¶
keryx fails at the point the value is used, naming the key and what it accepts.
| Situation | What you get |
|---|---|
Unknown providers.<capability> |
unknown provider: <capability>="<name>" (available: …) listing the registered adapters |
Unknown storage.provider |
unknown provider: storage.provider="<name>" (available: azure, file, gcs, mem, s3) |
storage.provider unset |
Not an error — local-only mode. Media sync commands report the store as unconfigured and skip. |
storage.s3.bucket unset with storage.provider: s3 |
storage.s3.bucket is not set |
Unknown auth.writeback.backend |
unknown writeback backend "<name>" (have: local, gitlab) |
Unknown auth.alerts.backend |
unknown alerts backend "<name>" (have: none, webhook, email) |
Unknown tls.source |
No error — anything other than localca degrades to a self-signed certificate, and HTTPS is still served |
| A theme keyword that does not exist | theme not found |
| No default theme for a type | no theme configured for this type — add one with \keryx theme add |
| Malformed YAML in any layer | The command refuses to run: failed to load configuration: … config: source could not be parsed: <path> document 0: yaml: line N: …. The path and line are named; keryx does not fall back to the other layers. |
The two config shapes a key can have, and why it matters¶
Some providers.* keys are scalars (providers.render: afmpeg) and some are
maps (providers.render.module: /path/to.wasm). YAML cannot give one key both
shapes, and neither can the layer stack — the highest-precedence layer's shape wins
outright and the other form resolves to empty.
The practical consequences are on configuration keys;
the short version is that the module-override keys under providers.render.* cannot be
combined with providers.render: afmpeg, and KERYX_FFMPEG_WASI is the working route.
Writing configuration from the tools¶
keryx theme addand friends writethemes.*into~/.keryx/themes.yamlor the project file, preserving comments and key order.keryx authwrites credentials into~/.keryx/accounts.yaml.- The studio Settings panel writes a fixed allowlist of
non-secret keys into the active project's
.keryx.yaml. It refuses every key outside that list, so no secret can be written through it.
Two of the keys on that allowlist do not do what the panel implies. The provider
pickers write providers.image.provider, providers.voice.provider and so on, but
the adapter is selected from the scalar providers.image — so a provider chosen in
the panel is not the one keryx uses. And git.auto_push ("push on save") is read by
nothing at all.
Hand-editing any of these files is supported and expected; nothing keeps a shadow copy.