Overview
Schemas define the available options with their types and default values. Once deployed, schemas must evolve carefully to avoid breaking existing deployments. The CLI enforces strict evolution rules to prevent breaking changes.
Allowed changes
Adding new namespaces
You can create new namespace directories at any time:
mkdir -p sentry-options/schemas/myrepo-newfeature
New namespaces must follow the naming convention: either {repo} (exact match) or {repo}-* (prefixed). For example, in the seer repo:
seer - Valid (exact match)
seer-autofix - Valid (prefixed)
seer-grouping - Valid (prefixed)
autofix - Invalid (missing prefix)
Adding new options
Adding new properties to an existing schema is always safe:
{
"version": "1.0",
"type": "object",
"properties": {
"existing.option": {
"type": "boolean",
"default": false,
"description": "Existing option"
},
"new.option": {
"type": "integer",
"default": 100,
"description": "Newly added option"
}
}
}
New options automatically use their default values until values are deployed via ConfigMap.
Removing options (conditionally)
Removing options from the schema is allowed, but you should verify the option is no longer referenced in any values files before removing it.
The CLI provides a workflow to check option usage:
# Step 1: Detect deleted options
sentry-options-cli validate-schema-changes \
--base-sha main \
--head-sha HEAD \
--repo myrepo \
--report-deletions > deletions.txt
# Step 2: Check if deleted options are still in use
sentry-options-cli check-option-usage \
--deletions "$(cat deletions.txt)" \
--root option-values/
If options are still in use, the second command will fail with the list of files that reference the deleted options.
Disallowed changes
The following changes are breaking and will cause CI validation to fail.
Removing namespaces
Once a namespace exists, it cannot be removed. Removing a namespace directory will fail validation:
Error: Namespace 'seer-autofix' was removed
Migration strategy: Contact DevInfra to coordinate a safe removal process. This typically involves:
- Removing all ConfigMap references from ops repo
- Removing all code references from service repo
- Removing values from sentry-options-automator
- Finally removing the schema
Changing option types
Changing the type field of an existing option is forbidden:
"rate.limit": {
- "type": "integer",
+ "type": "number",
"default": 100
}
Error message:
Option 'myrepo.rate.limit' type changed from 'integer' to 'number'
Migration strategy: Add a new option with the desired type and deprecate the old one:
{
"rate.limit": {
"type": "integer",
"default": 100,
"description": "[DEPRECATED] Use rate.limit.v2"
},
"rate.limit.v2": {
"type": "number",
"default": 100.0,
"description": "Rate limit (supports decimals)"
}
}
Changing array item types
For array options, changing the items.type is also forbidden:
"allowed.ids": {
"type": "array",
"items": {
- "type": "integer"
+ "type": "string"
},
"default": []
}
Error message:
Option 'myrepo.allowed.ids' array items type changed from 'integer' to 'string'
Changing default values
Default values cannot be changed once set:
"feature.enabled": {
"type": "boolean",
- "default": false,
+ "default": true,
"description": "Enable feature"
}
Error message:
Option 'myrepo.feature.enabled' default value changed from false to true
Rationale: Services may rely on schema defaults before ConfigMaps are deployed. Changing defaults would silently alter behavior.
Migration strategy: To effectively change a default:
- Deploy new values to all targets in sentry-options-automator first
- Wait for ConfigMaps to propagate to all regions
- Then you can add a new option with the desired default
Validation rules
Schema structure
Every schema must include:
version - Semver string (e.g., "1.0")
type - Must be "object"
properties - Map of option definitions
Each property must have:
type - One of: string, integer, number, boolean, array
default - Default value matching the declared type
description - Human-readable description
items - Required if type is array, specifies array element type
Type validation
The CLI validates that default values match their declared types:
Valid:
{"type": "integer", "default": 42}
{"type": "number", "default": 3.14}
{"type": "number", "default": 5}
{"type": "boolean", "default": true}
{"type": "string", "default": "hello"}
{"type": "array", "items": {"type": "string"}, "default": ["a", "b"]}
Invalid:
{"type": "integer", "default": 5.5} // Error: floats not allowed for integer
{"type": "boolean", "default": "true"} // Error: string not boolean
{"type": "array", "items": {"type": "integer"}, "default": ["a"]} // Error: wrong item type
Name validation
Namespace and target names must be valid Kubernetes label components:
- Lowercase alphanumeric,
-, or . only
- Must start and end with alphanumeric
Valid: relay, my-service, my.service, a1-b2.c3
Invalid: MyService, my_service, -service, service.
CI integration
Service repo validation
Add this workflow to validate schema changes in pull requests:
.github/workflows/validate-sentry-options.yml:
name: Validate sentry-options schema
on:
pull_request:
paths:
- 'sentry-options/schemas/**'
jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
with:
fetch-depth: 0 # Required for comparing base and head commits
- uses: getsentry/sentry-options/.github/actions/validate-schema@sha
with:
schemas-path: sentry-options/schemas
This composite action validates:
- Schema structure and syntax
- No breaking changes vs base commit
- Namespace naming conventions
Automator repo validation
The sentry-options-automator repo validates:
- All values files against their schemas (fetched from repos.json)
- No duplicate keys within a target
- No unknown namespaces
Testing schema changes locally
Before committing schema changes, test them locally:
# Validate schema structure
sentry-options-cli validate-schema --schemas sentry-options/schemas
# Compare against previous version (requires git)
sentry-options-cli validate-schema-changes \
--base-sha HEAD~1 \
--head-sha HEAD \
--repo myrepo
Common validation errors
Invalid '': character ‘X’ not allowed
Cause: Namespace or target name contains invalid characters (uppercase, underscores, etc.)
Fix: Use lowercase alphanumeric, -, or . only
Property ‘option.name’ default value does not match schema
Cause: The default value doesn’t match the declared type
Fix: Ensure the default value matches the type:
"type": "integer" requires whole numbers
"type": "string" requires quoted strings
"type": "array" requires arrays with items matching the items.type
Additional properties are not allowed
Cause: Extra fields in property definition or unknown options in values files
Fix: Only include allowed fields: type, default, description, items (for arrays)
“version” is a required property
Cause: Schema is missing the required version field
Fix: Add "version": "1.0" to the top level of your schema