sentry-options-validation library is the core validation engine that powers both the CLI and client libraries. It provides schema loading, JSON Schema validation, and automatic value reloading capabilities.
Overview
This library is used internally by:- CLI: Validates YAML files against schemas and generates JSON output
- Rust client: Loads schemas and values, watches for file changes
- Python client: Via PyO3 bindings to the Rust client
- Schema validation using JSON Schema
- Thread-safe value storage with automatic reloading
- Kubernetes-compatible naming validation
- Efficient schema compilation and caching
Core types
SchemaRegistry
Loads and manages namespace schemas from disk.Map of namespace names to compiled schemas
Methods
Creates an empty schema registry
Loads all schemas from a directory structure. Expects
schemas/{namespace}/schema.json layout.Errors: Returns ValidationError if directory doesn’t exist or any schema is invalidValidates a complete values object against a namespace schemaParameters:
namespace: Namespace namevalues: JSON object with option key-value pairs
UnknownNamespace or ValueError with validation detailsRetrieves a compiled schema by namespace name
Loads and validates JSON values from directory. Expects
{values_dir}/{namespace}/values.json structure.Returns: Tuple of (values map, generated_at timestamps by namespace)Note: Skips namespaces without values.json filesUsage example
NamespaceSchema
Compiled schema for a single namespace with validation and metadata.Namespace identifier
Metadata for each option defined in the schema
Compiled JSON Schema validator (private)
Methods
Validates values object against this namespace schemaErrors: Returns
ValueError with detailed validation errors including field pathsReturns the default value for an option key, or None if key doesn’t exist
OptionMetadata
Metadata extracted from a schema property definition.JSON Schema type (“string”, “integer”, “number”, “boolean”, “array”, “object”)
Complete property schema definition including type, default, description
Default value for the option
ValuesWatcher
Background thread that polls for file changes and reloads values automatically.Signal to stop the watcher thread
Handle to the background polling thread
Methods
new(values_path: &Path, registry: Arc<SchemaRegistry>, values: Arc<RwLock<ValuesByNamespace>>)
ValidationResult<ValuesWatcher>
Creates and starts a background watcher threadParameters:
values_path: Directory containing namespace values.json filesregistry: Schema registry for validationvalues: Shared values map that will be updated on changes
SENTRY_OPTIONS_SUPPRESS_MISSING_DIR=1)Stops the watcher thread and waits for it to join (may take up to 5 seconds)
Returns whether the watcher thread is still running
Behavior
- Polls every 5 seconds for file modifications
- Tracks most recent mtime across all
values.jsonfiles - On change: validates all namespaces, updates values atomically
- If validation fails: keeps old values for all namespaces
- Emits Sentry transactions with reload metrics and propagation delay
- Thread automatically stops when
ValuesWatcheris dropped
Usage example
Validation errors
TheValidationError enum covers all validation failure cases:
Schema file is invalid or doesn’t match meta-schema
Values don’t match schema. Error string contains field paths and descriptions.
Referenced namespace doesn’t exist in registry
Internal library error (meta-schema compilation failure, etc.)
File system error reading schema or values
Invalid JSON in schema or values file
Multiple validation errors bundled together
Invalid Kubernetes-style name (must be lowercase alphanumeric with
- or .)Error formatting
Helper functions
resolve_options_dir()
Resolves the options directory using fallback chain:
SENTRY_OPTIONS_DIRenvironment variable/etc/sentry-options(if exists)sentry-options/(local fallback)
validate_k8s_name_component()
Validates that a name follows Kubernetes naming rules:
- Lowercase letters, digits,
-,.only - Must start and end with alphanumeric
Constants
/etc/sentry-options - Production path where ConfigMaps are mountedsentry-options - Local development fallback pathSENTRY_OPTIONS_DIR - Environment variable to override options directorySENTRY_OPTIONS_SUPPRESS_MISSING_DIR - Set to 1 or true to suppress missing directory warningsType aliases
Standard result type for validation operations
Map structure:
namespace -> (option_key -> value)Internal usage by CLI
The CLI usesSchemaRegistry to validate YAML files and merge them into JSON output:
Internal usage by Rust client
The Rust client usesSchemaRegistry + ValuesWatcher for runtime value access:
Observability
TheValuesWatcher emits Sentry transactions on each reload with:
sentry_options.reloadNamespace name (e.g.,
relay)Time taken to load and validate values in milliseconds
RFC3339 timestamp when values were applied
RFC3339 timestamp from values.json (if present)
Time between generation and application in seconds (if
generated_at available)Thread safety
SchemaRegistryusesArc<NamespaceSchema>for efficient sharingValuesWatcherusesArc<RwLock<ValuesByNamespace>>for concurrent reads- Writer may starve under heavy read load (standard
RwLockbehavior) - Watcher thread automatically stops when
ValuesWatcheris dropped
Validation logic
-
Schema validation (at load time):
- Schema must match
namespace-schema.jsonmeta-schema - Must have
versionfield - All properties require
type,default,description - Default values must match their declared type
- Namespace names must be valid Kubernetes identifiers
- Schema must match
-
Value validation (at runtime):
- Values validated against compiled JSON Schema
- Unknown options rejected (
additionalProperties: falseinjected) - Type mismatches reported with field paths
- All errors collected and reported together
Dependencies
Key external crates:jsonschema- JSON Schema Draft 7 validationserde_json- JSON parsing and manipulationsentry- Observability and error trackingthiserror- Error type definitions