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 policy

Ruleset validation is strict because it occurs before activation. Record ingestion defaults to skip-and-count so malformed rows do not terminate a stream. HARD_FAIL provides 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 op that is not one of the supported operators is rejected (UNKNOWN_OP); it is never silently ignored.
  • Unknown action — an action that is not flag / block / score / review / approve is rejected (UNKNOWN_ACTION); a typo cannot silently become a different action.
  • Malformed nested condition — a parse error anywhere inside an and / or / not tree fails the whole rule; nested errors are never swallowed.
  • Condition nesting too deep — an and/or/not tree or a parenthesized sql: 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_regex pattern 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_score rule is rejected at compile time.
  • register_model(name, path) throws.
🚧

A failed activation does not replace a running ruleset

If 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
ModeValuesDefaultBehavior
ingest_error_modeSKIP_AND_COUNTDrop the unparseable record, increment messages_skipped and error_counts.
SKIP_TO_DEAD_LETTERRoute the bad record to a dead-letter log instead of dropping it.
HARD_FAILAbort the batch on the first ingest error.
type_mismatch_modeNULL_ON_TYPE_ERRORTreat a mismatched field value as null for that field.
COERCEAttempt a safe type conversion.
HARD_FAIL_TYPEAbort 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.

ClassBaseRaised when
BlazeRulesErrorBase class for all BlazeRules errors; catch it to handle any of the below.
BlazeRulesConfigErrorBlazeRulesErrorConfiguration is invalid — unknown fields, conflicting options, an unbuilt feature requested (e.g. register_model with ONNX off).
BlazeRulesParseErrorBlazeRulesErrorThe rule file fails to parse — malformed YAML or an unparseable SQL expression.
BlazeRulesSchemaErrorBlazeRulesErrorSchema 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

SymptomWhat it meansFix
load_rules raises a parse errorBad YAML, or an unparseable sql: expressionValidate the YAML; check the SQL form against the examples in rules.yaml.
"unknown field" / "duplicate id" on loadA typo'd key, or two rules share an idCorrect the key; make every rule id unique.
Regex rule rejected at loadRE2 cannot compile the patternFix the regex / not_regex value; RE2 does not accept all PCRE syntax.
Lookup error at loadMissing CSV, wrong column, or bad rowsConfirm 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 throwsLibrary built with BLAZERULES_ENABLE_ONNX=OFFRebuild with ONNX enabled, or remove the model_score rule. See Troubleshooting.
messages_skipped > 0, records missingRecords failed ingest under SKIP_AND_COUNTInspect error_counts / error_samples; switch to SKIP_TO_DEAD_LETTER to capture payloads, or HARD_FAIL to stop.
A field is always null in matchesA value did not match the bound type under NULL_ON_TYPE_ERRORConfirm the field type; use COERCE, or add explicit fields: hints / schema.
Batch aborts on a single bad recordingest_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


Did this page help you?