Skip to main content
Ziro’s config loaders are forgiving: a value they cannot use falls back to its default instead of stopping the agent. That keeps a session running, but it also means a typo like enabeld: true can be ignored without anything on screen. Two tools close that gap: JSON Schemas for your editor, and ziro config doctor.

In your editor

Ziro publishes a JSON Schema for every config file at https://ziro-agent.com/schemas/v1/. Every config file Ziro writes (ziro init, ziro agents, ziro migrate-config, the capability manager) starts with a line that points at its schema:
With a YAML language server installed (in VS Code, the Red Hat YAML extension), that line gives you completion, hover text for every key, and a red underline on a misspelled key or a wrong type. Add the line yourself to a file you created by hand. The schemas accept what Ziro accepts: ${VAR} tokens, a single string where a list is expected, an MCP server without transport in a per-agent overlay, a guardrails backend that leaves type to a lower layer.

ziro config doctor

ziro config doctor checks every config file Ziro reads, across the project, user and bundled layers, and prints each problem with its file, line, and what Ziro does about it. It never changes a file.
It exits 0 when there are no errors (warnings alone are fine), 1 on any error, and 2 on a usage error, so it works as a CI step or a pre-commit hook. It reports two kinds of issue. Errors: the file says one thing and Ziro does another.
  • A YAML syntax error, or a file that is not a mapping.
  • An unknown key or section (a typo).
  • A wrong type or an invalid value.
  • A key written twice in the same mapping. YAML keeps the later one.
  • An MCP server Ziro will not use: invalid auth, an args that is neither a list nor a string, or an unknown transport.
  • A theme with a missing colour slot, or a colour that cannot be rendered.
  • A flavour overlay for a policy file that does not exist.
Warnings: legal, but probably not what you meant.
  • registry.yaml names a default agent that does not exist.
  • A flavour lists an agent that does not exist.
  • An untrusted project has permissions, mcp, hooks or plugins config (ignored until you trust it).
  • An untrusted project sets subagents.routing or subagents.model_defaults (ignored), or a subagent or resources limit that can only tighten the lower layers.
  • An untrusted project’s subagent file replaces a user or bundled subagent (ignored) or sets model, provider or reasoning_effort (ignored).
  • A legacy split file is not read because the same folder’s settings.yaml already has that section.
Run it after editing config by hand, and before reporting a bug: “this setting does nothing” is usually a typo the doctor names in one line.

What Ziro does with a value it cannot use

The effect depends on the section. The doctor prints the same text. An unknown key is ignored everywhere except plugins, where any mistake disables plugins for the agent: a broken plugin gate must never open up.

Values Ziro reads generously

These are not errors, and neither the schema nor the doctor flags them:
  • One string for a list of names: denylist: web:web_fetch, allowlist: search, deny: "github*", ref_extensions: md each mean a one-item list. A number or mapping in such a list is read as text, so a mistake there still denies or exposes nothing extra.
  • Numbers in stdio MCP args are passed as text: args: [--port, 8080].
  • An MCP auth block without type is OAuth. auth: null is the same as no auth.
  • An empty list (allow: with nothing after it) is an empty list.
  • Text fields in meta and persona accept numbers (name: 2024); a YAML false (intro: no) is read as unset.

Next steps

Configuration

How layers resolve and merge.

Agent file reference

Every section of settings.yaml.