vectordotdev/vector · error
schema definition must exist
Error message
schema definition must exist
What it means
While collecting definitions eligible for inlining, `visit_root_schema` looks up each candidate `$ref` name in the root schema's `definitions` map and asserts it exists. The panic fires when a definition name appears in the inline-candidate list but is missing from `root.definitions`, meaning the root schema's definitions were mutated or built inconsistently.
Solutions
- Ensure visitors that mutate `definitions` run in the intended order (inline_single's own visiting before any removal-based visitor)
- Check that no other code drains/moves `root.definitions` before `visit_root_schema`
- Pin consistent versions of vector-config-related crates in the workspace
- Reproduce with a minimal `RootSchema` and add debug logging of definition names
Example fix
// before (wrong order) schema_pipeline.push(RemovingVisitor::default()); schema_pipeline.push(InlineSingleVisitor::default()); // after schema_pipeline.push(InlineSingleVisitor::default()); schema_pipeline.push(RemovingVisitor::default());
Defensive patterns
Strategy: validation
Validate before calling
fn validate_refs_resolve(root: &RootSchema) -> Result<(), String> {
for name in root.definitions.keys() {
if !root.definitions.contains_key(name) {
return Err(format!("dangling schema definition: {name}"));
}
}
Ok(())
} Type guard
fn definition_exists<'a>(root: &'a RootSchema, name: &str) -> Option<&'a Schema> { root.definitions.get(name) } Try / catch
let schema = root.definitions.get(def_name.as_ref()).ok_or_else(||
anyhow::anyhow!("schema definition {def_name:?} missing from root definitions"))?; Prevention
- Run visitor pipelines in the documented order (inline before prune)
- Never drain or move root.definitions before visiting
- Use a fresh RootSchema per generation; avoid re-visiting mutated schemas
When it happens
Trigger: Calling `visit_root_schema` on a `RootSchema` whose `definitions` map lacks an entry referenced by an earlier enumeration pass — e.g. the definitions were moved/drained before this visitor runs, or a composed visitor pipeline mutated definitions out of order.
Common situations: Chaining schema visitors in a non-standard order (running inline_single after another visitor that removes definitions); version skew between vector-config crates that changed visitor ordering.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- referenced schema must exist in definitions
- schema definition must exist
- schema reference should exist
- all-of subschemas must be present here
- Encountered schema with subschema validation that wasn't…
AI-assisted analysis of vectordotdev/vector@bdb87aeaa4 (2026-09-16).
Data as JSON: /api/errors/75d0808e3d5c8e55.
Report an issue: GitHub.
Appendix: source
Thrown at lib/vector-config/src/schema/visitors/inline_single.rs:61
let occurrence_map = occurrence_visitor.occurrence_map;
self.eligible_to_inline = occurrence_map
.into_iter()
// Filter out any schemas which have more than one occurrence, as naturally, we're
// trying to inline single-use schema references. :)
.filter_map(|(def_name, occurrences)| (occurrences == 1).then_some(def_name))
// However, we'll also filter out some specific schema definitions which are only
// referenced once, specifically: component base types and component types themselves.
//
// We do this as a lot of the tooling that parses the schema to generate documentation,
// and the like, depends on these schemas existing in the top-level definitions for easy
// lookup.
.filter(|def_name| {
let schema = root
.definitions
.get(def_name.as_ref())
.and_then(Schema::as_object)
.expect("schema definition must exist");
is_inlineable_schema(def_name.as_ref(), schema)
})
.map(|s| s.as_ref().to_string())
.collect::<HashSet<_>>();
// Now run our own visitor logic, which will use the inline eligibility to determine if a
// schema reference in a being-visited schema should be replaced inline with the original
// referenced schema, in turn removing the schema definition.
visit::visit_root_schema(self, root);
// Now remove all of the definitions for schemas that were eligible for inlining.
for schema_def_name in self.eligible_to_inline.drain() {
debug!(
referent = schema_def_name,
"Removing schema definition from root schema."
);
View on GitHub (pinned to bdb87aeaa4)