A schema is only useful once docmeta knows which schema applies to which file. In a real repo, several signals compete to answer that question: a flag on the command line, a $schema key inside the document, a directory rule in your config, a repo-wide default. docmeta settles the competition with a fixed precedence order — and once you know that order, wiring schemas to documents becomes predictable instead of mysterious.
This page documents the precedence chain, the three kinds of schema reference you can use anywhere a schema is named, and how docmeta detects a schema’s JSON Schema dialect.
For every file, docmeta builds a schema set — the list of schemas that file will be validated against — by checking five sources in order. The first source that yields a schema wins, and the search stops there. Nothing lower in the list is consulted.
CLI -s/--schema — if you pass one or more --schema flags, they apply to every file in the run and override everything else. Repeatable; the flags together form the set.
The file’s own $schema key — a $schema field in the document’s metadata. May be a single string or a list of strings.
The first matching overrides entry in config — config overrides are checked in order; the first whose glob matches the file path supplies the set.
Config schemas — the repo-wide default list in docmeta.config.yaml.
The built-in default — if nothing above matched, docmeta uses google:okf:0.1.
Here is the same chain as a quick-reference table:
Order
Source
Scope
Notes
1
CLI -s/--schema
All files in the run
Repeatable; overrides everything below.
2
File $schema key
That one file
String or list of strings. Reserved key — stripped before validation.
3
Config overrides
Files matching a glob
First matching entry wins; later entries ignored.
4
Config schemas
All files (repo default)
Used when no override matched.
5
Built-in default
All files (last resort)
google:okf:0.1.
Levels 3 and 4 come from your docmeta.config.yaml. Here is the config the worked example below assumes — a repo-wide default plus one directory override:
docmeta.config.yaml
# Level 4: the repo-wide default applied to every file...
schemas:
- google:okf:0.1
# Level 3: ...unless a file matches an override glob, checked top to bottom.
overrides:
- files: "api/**"
schemas:
- ./schemas/api.schema.json
Each overrides entry pairs a files glob with a schemas list. Entries are tried in order, and the first whose glob matches the file supplies the set. (For every config key, type, and default, see the Configuration reference.)
When a document names its own schema with a $schema key, that key is a directive to docmeta, not part of the document’s metadata. docmeta strips $schema out of the metadata before handing it to the validator.
This matters for one specific case: a schema with "additionalProperties": false rejects any field it doesn’t declare. Without special handling, a document carrying $schema: would fail against such a schema — because $schema isn’t one of the schema’s declared properties. Because docmeta removes $schema first, that never happens. You never need to add $schema to your schema’s properties, and a self-describing document validates cleanly against even the strictest schema.
The $schema value can be a single reference or a list:
Everywhere a schema is named — a --schema flag, a $schema key, a config entry — the value is a reference, and docmeta classifies it into one of three kinds by its shape. You don’t declare the kind; docmeta infers it.
Built-in
A vendor:name:version id with no path separators and not ending in .json.
Example: google:okf:0.1
Resolved from the schemas bundled into docmeta. A typo’d id (e.g. an unknown vendor) is reported as an unknown built-in, not silently treated as a missing file.
File
A path that ends in .jsonor contains a path separator (/ or \).
Read from the local filesystem. Relative paths resolve against the current working directory.
URL
Anything starting with http:// or https://.
Example: https://example.com/schemas/okf-1.0.json
Fetched over the network with a 10-second timeout and cached for the run, so the same URL is downloaded only once even across thousands of files.
URL references are the foundation for governing one schema across many repos — a central, versioned schema URL that every consumer points at. That workflow, including the fetch timeout and caching behavior in depth, is covered in Govern a shared schema by URL.
When a file’s schema set contains more than one reference, docmeta validates the file against every schema in the set and reports the union of all violations, each tagged with the schema that produced it. A file passes only if it satisfies all of them.
A multi-schema set is what you get when you name several schemas at a single precedence level:
several --schema flags on the command line,
a list-valued $schema key in a document,
or multiple entries in one config overrides rule or in config schemas.
This is useful for layering a shared organizational schema with a local one — for example, validate against a company-wide house-style.schema.jsonand a team-specific api.schema.json at once. Each schema is compiled and cached separately, so layering is cheap.
Because the file must satisfy every schema in the set, the strictest member governs. If any schema in the set sets "additionalProperties": false, an unknown key fails the file even when another schema in the set allows it. Keep that in mind when combining a lenient shared schema with a strict local one — the strict one wins on every rule it imposes.
JSON Schema has evolved through several versions, called dialects (draft-04, draft-06, draft-07, 2019-09, 2020-12). A schema written for one dialect can fail to compile under another, so docmeta reads each schema’s own $schema line — the URI at the top of the schema file that points at the dialect’s meta-schema (the schema that defines the dialect itself) — and selects the matching validation engine.
docmeta supports these dialects:
Dialect
Detected from a $schema URI containing
2020-12
2020-12 (also the fallback)
2019-09
2019-09
draft-07
draft-07 or draft/7
draft-06
draft-06 or draft/6 (shares the draft-07 engine)
draft-04
draft-04 or draft/4
If a schema omits its $schema line or uses an unrecognized one, docmeta falls back to 2020-12 — the dialect of the built-in schemas. This auto-detection is why a schema you fetch from a remote URL that targets draft-07 validates correctly alongside a local 2020-12 schema in the same run.
For the full lookup table of precedence, reference kinds, and dialects in one place, see the Schema resolution reference.