Troubleshooting

Common BlazeRules symptoms — import errors, missing features, slow evaluation, type surprises — with the cause and the fix for each.

Most BlazeRules integration failures come from module discovery, a feature omitted at build time, or a schema mismatch. The entries below map symptoms to likely causes, corrective actions, and diagnostic data to collect.

📘

First check: import and backend

First confirm that the module imports and reports a SIMD backend. A version and backend result (for example 0.5.4 neon on Apple Silicon) confirms that the native module loaded successfully; subsequent failures are configuration or runtime issues rather than installation failures.

export PYTHONPATH="$PWD/cmake-build-release"
python -c "import blazerules; print(blazerules.__version__, blazerules.simd_backend())"

Symptom → cause → fix

SymptomLikely causeFix
ImportError / ModuleNotFoundError: blazerulesThe build directory is absent from PYTHONPATHSet PYTHONPATH to the build directory, for example export PYTHONPATH="$PWD/cmake-build-release".
model_score rule rejected at compile; register_model() throwsLibrary built with BLAZERULES_ENABLE_ONNX=OFFRebuild with -DBLAZERULES_ENABLE_ONNX=ON, or remove the model_score rule.
import blazerules_io fails, or blazerules_io.has_kafka is FalseIO module not built, or Kafka sub-flag offRebuild with -DBLAZERULES_IO=ON (and -DBLAZERULES_IO_KAFKA=ON). Check has_kafka / has_avro / has_protobuf for the specific connector/decoder.
Evaluation is much slower than expectedDebug build or unnecessary result materializationBuild Release (-DCMAKE_BUILD_TYPE=Release or a release preset); use OutputDetail.COUNTS or CODES for compact results, DECISIONS for routing, and BITMASKS only for per-rule masks. Evaluate batches rather than individual records.
Numeric fields behave as integers; a float rule never matchesSchema was inferred and a field came out as INT32Add explicit fields: hints in the YAML (e.g. amount: {type: float32}) or build the engine with an explicit schema via RuleEngine(schema, config).
Records are silently missing from outputRecords were skipped during ingestInspect result.error_counts and result.error_samples. Adjust ingest_error_mode (SKIP_TO_DEAD_LETTER to capture, HARD_FAIL to stop) and type_mismatch_mode. See Error Reference.
A field is always null even when presentValue didn't match the bound type under NULL_ON_TYPE_ERRORConfirm the field's type; try type_mismatch_mode = COERCE, or pin the type with fields: hints / explicit schema.
s3:// rule or lookup fails to loadAWS profile/region/endpoint not set, or object path wrongSet BLAZERULES_AWS_PROFILE / BLAZERULES_AWS_REGION / BLAZERULES_AWS_ENDPOINT_URL (or the set_aws_* calls); BlazeRules reads exact-object s3://bucket/key URIs, not prefixes.
🚧

Watch out for inference inferring INT32

Without fields: hints or an explicit schema, BlazeRules infers types from the first batch. A field whose initial values are integral may bind as INT32; subsequent fractional comparisons then fail type validation or evaluate as configured by the mismatch policy. Ambiguous numeric fields should be typed explicitly.

Performance checklist

If throughput or latency is the problem, walk this list before profiling:

  • Release build — use -DCMAKE_BUILD_TYPE=Release or a release preset (see Deployment).
  • Batch, don't drip — collect records and call the engine once per batch; common streaming batch sizes are 2K–64K rows.
  • Right output detailOutputDetail.COUNTS for aggregate-only runs, CODES for compact routing, DECISIONS for normal row-level output, and BITMASKS only when downstream needs per-rule masks.
  • Use Arrow for existing typed data to avoid JSON parsing. For padded or file-backed JSON, use evaluate_ndjson_padded(payload, logical_size) or evaluate_ndjson_file(...).
  • Keep entity affinity for window workloads — window rules read prior-batch state; partition by entity.
  • Don't carry huge unused JSON fields — skipped bytes are still bytes the parser scans.

Collect this before filing an issue

A reproducible report needs the build identity, the selected backend, and a minimal failing case. Gather:

import blazerules
print("version:", blazerules.__version__)
print("backend:", blazerules.simd_backend())
print("cpu:", blazerules.cpu_features_summary())
  • The output of the three calls above.
  • A minimal rules.yaml that reproduces the problem (smallest ruleset that still shows it).
  • A single sample record (JSON/NDJSON) that triggers the behavior.
  • Whether the library was built with ONNX and IO, including the selected preset or flags.

Project website: https://blazerules.dev. Source code and issues: github.com/purijs/blazerules.

Related documentation


Did this page help you?