Error Reference
The two error layers in BlazeRules — strict rule/schema activation versus tolerant per-record ingest — and what each error means.
BlazeRules separates errors into two policy layers. Rule and schema activation is strict: an invalid ruleset is rejected before activation. Per-record ingest is tolerant by default: one malformed record does not abort a batch. The error domain identifies whether remediation belongs in ruleset activation or record ingestion.
Activation and ingest policyRuleset validation is strict because it occurs before activation. Record ingestion defaults to skip-and-count so malformed rows do not terminate a stream.
HARD_FAILprovides strict ingest behavior.
Layer 1 — strict activation
load_rules(...) and explicit schema binding compile and validate the complete configuration before activation. The following conditions fail before activation, so an invalid ruleset never becomes active:
- Bad YAML — the file does not parse.
- Unknown fields — a rule or config key the parser does not recognize.
- Unknown operator — an
opthat is not one of the supported operators is rejected (UNKNOWN_OP); it is never silently ignored. - Unknown action — an
actionthat is notflag/block/score/review/approveis rejected (UNKNOWN_ACTION); a typo cannot silently become a different action. - Malformed nested condition — a parse error anywhere inside an
and/or/nottree fails the whole rule; nested errors are never swallowed. - Condition nesting too deep — an
and/or/nottree or a parenthesizedsql:expression nested beyond the depth limit is rejected instead of risking a stack overflow. - Duplicate rule IDs — two rules share an
id. - Invalid regex — a
regex/not_regexpattern RE2 rejects. - Bad lookup files — a missing CSV, wrong columns, or unparseable rows for a referenced
lookup. - Type / operator mismatches — an operator applied to an incompatible field type.
Two ONNX-specific cases fail at the same layer when the library was built with BLAZERULES_ENABLE_ONNX=OFF:
- A
model_scorerule is rejected at compile time. register_model(name, path)throws.
A failed activation does not replace a running rulesetIf activation fails during a hot reload, the previous ruleset remains active.
Layer 2 — tolerant ingest
Once rules are active, two EngineConfig modes govern per-record failures. The defaults skip or null invalid data; hard-fail modes stop the batch.
import blazerules
config = blazerules.EngineConfig()
config.ingest_error_mode = blazerules.IngestErrorMode.SKIP_AND_COUNT # default
config.type_mismatch_mode = blazerules.TypeMismatchMode.NULL_ON_TYPE_ERROR # default| Mode | Values | Default | Behavior |
|---|---|---|---|
ingest_error_mode | SKIP_AND_COUNT | ✓ | Drop the unparseable record, increment messages_skipped and error_counts. |
SKIP_TO_DEAD_LETTER | Route the bad record to a dead-letter log instead of dropping it. | ||
HARD_FAIL | Abort the batch on the first ingest error. | ||
type_mismatch_mode | NULL_ON_TYPE_ERROR | ✓ | Treat a mismatched field value as null for that field. |
COERCE | Attempt a safe type conversion. | ||
HARD_FAIL_TYPE | Abort on the first type mismatch. |
Per-batch BatchResult fields report ingest failures: messages_skipped, error_counts, and error_samples. A malformed row in an NDJSON stream is recorded and skipped under the default policy. Each error sample and SKIP_TO_DEAD_LETTER record includes the error code, column_name, and parser message, such as invalid JSON near field 'metrics'. See Observability.
Python error classes
Activation-layer failures surface as a small hierarchy. Catch the base class to handle any of them, or a specific subclass to react to one cause.
| Class | Base | Raised when |
|---|---|---|
BlazeRulesError | — | Base class for all BlazeRules errors; catch it to handle any of the below. |
BlazeRulesConfigError | BlazeRulesError | Configuration is invalid — unknown fields, conflicting options, an unbuilt feature requested (e.g. register_model with ONNX off). |
BlazeRulesParseError | BlazeRulesError | The rule file fails to parse — malformed YAML or an unparseable SQL expression. |
BlazeRulesSchemaError | BlazeRulesError | Schema is inconsistent — a type/operator mismatch or a field that cannot be bound. |
import blazerules
engine = blazerules.RuleEngine()
try:
engine.load_rules("rules.yaml")
except blazerules.BlazeRulesParseError as e:
print("rule file did not parse:", e)
except blazerules.BlazeRulesSchemaError as e:
print("schema/type problem:", e)
except blazerules.BlazeRulesError as e:
print("activation failed:", e)Symptom → meaning → fix
| Symptom | What it means | Fix |
|---|---|---|
load_rules raises a parse error | Bad YAML, or an unparseable sql: expression | Validate the YAML; check the SQL form against the examples in rules.yaml. |
| "unknown field" / "duplicate id" on load | A typo'd key, or two rules share an id | Correct the key; make every rule id unique. |
| Regex rule rejected at load | RE2 cannot compile the pattern | Fix the regex / not_regex value; RE2 does not accept all PCRE syntax. |
| Lookup error at load | Missing CSV, wrong column, or bad rows | Confirm the path (relative to the rules file) and that the CSV uses the right column (value / value / cidr). |
model_score rejected at compile / register_model throws | Library built with BLAZERULES_ENABLE_ONNX=OFF | Rebuild with ONNX enabled, or remove the model_score rule. See Troubleshooting. |
messages_skipped > 0, records missing | Records failed ingest under SKIP_AND_COUNT | Inspect error_counts / error_samples; switch to SKIP_TO_DEAD_LETTER to capture payloads, or HARD_FAIL to stop. |
| A field is always null in matches | A value did not match the bound type under NULL_ON_TYPE_ERROR | Confirm the field type; use COERCE, or add explicit fields: hints / schema. |
| Batch aborts on a single bad record | ingest_error_mode = HARD_FAIL (or HARD_FAIL_TYPE) | Expected under hard-fail; relax to SKIP_AND_COUNT / SKIP_TO_DEAD_LETTER if one bad record should not stop the batch. |
Related documentation
Updated about 2 months ago