Troubleshooting

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

Most BlazeRules issues trace back to one of three things: the module isn't on the path, an optional feature wasn't compiled in, or the schema was inferred differently than you expected. This page maps each symptom to its cause and fix, and ends with what to collect before filing an issue.

📘

First check: import and backend

Before anything else, confirm the module imports and reports a SIMD backend. If this prints a version and a backend (for example 0.1.0 neon on Apple M1), the build is sound and the problem is configuration, not installation.

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 isn't on PYTHONPATHexport PYTHONPATH="$PWD/cmake-build-release" (or wherever you built the module), then re-run.
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 if you don't need ONNX.
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 emitting more detail than neededBuild Release (-DCMAKE_BUILD_TYPE=Release or a release preset); set output_detail = OutputDetail.DECISIONS unless you truly need BITMASKS. Batch records — never call the engine per record.
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

When you don't supply fields: hints or an explicit schema, BlazeRules infers types from the first batch. A field whose first observed values look integral can be bound as INT32, after which a rule comparing it to a fractional value may never match. If a numeric rule behaves oddly, pin the field type rather than relying on inference.

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.DECISIONS for routing; OutputDetail.BITMASKS only when downstream needs per-rule masks.
  • Prefer Arrow when data is already typed — skip JSON parsing you don't need; use evaluate_ndjson_padded(...) / evaluate_ndjson_file(...) for padded or memory-mapped JSON.
  • 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 / IO and which preset or flags you used.

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

Where to go next