Did you check docs and existing issues?
Python version (python --version)
Python 3.12.0
Operating system/version
26.5
NeMo-Guardrails version (if you must use a specific version and not the latest
0.22.0
Describe the bug
The built-in detect_regex_pattern action correctly detects forbidden regex patterns during streaming output rail execution (logs confirm the match), but the streaming framework does not block the content. The matched output is streamed to the client as if no violation occurred.
Steps To Reproduce
- Configure output rails with streaming enabled and
regex check output:, e.g.
models:
- type: main
engine: openai
parameters:
base_url: "https://INSERT_ME/v1"
model_name: "INSERT_ME"
api_key: "INSERT_ME"
rails:
output:
flows:
- regex check output
streaming:
enabled: true
chunk_size: 200
context_size: 50
stream_first: true
config:
regex_detection:
output:
patterns:
- "\\bconfidential\\b"
- "\\bsecret\\b"
streaming: true
- Start the server
- Send a request, e.g.
curl -N -X POST http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "your-model",
"messages": [{"role": "user", "content": "Tell me about the movie Fight Club"}],
"stream": true
}'
- Observe the logs:
INFO:nemoguardrails.actions.action_dispatcher:Executing registered action: detect_regex_pattern
INFO:nemoguardrails.library.regex.actions:Regex pattern matched: \bfight\s+club\b
The pattern matches, but the response is not blocked; the full LLM output streams to the client
Expected Behavior
When the regex pattern matches in a streaming output chunk, the stream should be terminated and a guardrails violation error should be returned:
{"error": {"message": "Blocked by regex check output rails.", "type": "guardrails_violation", "param": "regex check output", "code": "content_blocked"}}
Actual Behavior
The regex match is logged but the content streams through unblocked. No error is returned to the client.
Cause
is_output_blocked looks for an output_mapping function attached to the action's metadata. If none is found, it falls back to default_output_mapping
detect_regex_pattern returns a RegexDetectionResult (a TypedDict / dict)
- Since a
dict is not bool and not int/float, default_output_mapping returns False — meaning "not blocked" — regardless of what is_match says.
Did you check docs and existing issues?
Python version (python --version)
Python 3.12.0
Operating system/version
26.5
NeMo-Guardrails version (if you must use a specific version and not the latest
0.22.0
Describe the bug
The built-in
detect_regex_patternaction correctly detects forbidden regex patterns during streaming output rail execution (logs confirm the match), but the streaming framework does not block the content. The matched output is streamed to the client as if no violation occurred.Steps To Reproduce
regex check output:, e.g.The pattern matches, but the response is not blocked; the full LLM output streams to the client
Expected Behavior
When the regex pattern matches in a streaming output chunk, the stream should be terminated and a guardrails violation error should be returned:
{"error": {"message": "Blocked by regex check output rails.", "type": "guardrails_violation", "param": "regex check output", "code": "content_blocked"}}Actual Behavior
The regex match is logged but the content streams through unblocked. No error is returned to the client.
Cause
is_output_blockedlooks for anoutput_mappingfunction attached to the action's metadata. If none is found, it falls back todefault_output_mappingdetect_regex_patternreturns aRegexDetectionResult(aTypedDict/dict)dictis notbooland notint/float,default_output_mappingreturnsFalse— meaning "not blocked" — regardless of whatis_matchsays.