JuliusBrussee/caveman · error · ErrRuleUnsupported
%w: %q (rule %q)
Error message
%w: %q (rule %q)
What it means
During rule compilation, a rule whose Type is RuleTypeJSONPath or RuleTypeHeader is rejected with ErrRuleUnsupported. Structured selection rules are not implementable against the byte-oriented redaction pass — Payload runs compiled regexes over the raw body and has no JSON tree or header context to apply those rule types to. The error names the offending type and rule.
Source
Thrown at shared/platform/redact/payload.go:573
var sb strings.Builder
for _, r := range sorted {
sb.WriteString(r.Name)
sb.WriteByte('\x1f')
sb.WriteString(r.Type)
sb.WriteByte('\x1f')
sb.WriteString(r.Pattern)
sb.WriteByte('\x1f')
sb.WriteString(r.Replacement)
sb.WriteByte('\x1e')
switch r.Type {
case RuleTypeBuiltin:
// A reference to the unconditional floor. Nothing to run, and
// nothing it could switch off.
continue
case RuleTypeRegex:
case RuleTypeJSONPath, RuleTypeHeader:
return nil, "", fmt.Errorf("%w: %q (rule %q)", ErrRuleUnsupported, r.Type, r.Name)
default:
return nil, "", fmt.Errorf("%w: %q (rule %q)", ErrRuleUnsupported, r.Type, r.Name)
}
if strings.TrimSpace(r.Name) == "" {
return nil, "", fmt.Errorf("%w: empty name", ErrInvalidRule)
}
if r.Pattern == "" {
return nil, "", fmt.Errorf("%w: rule %q has an empty pattern", ErrInvalidRule, r.Name)
}
re, err := regexp.Compile(r.Pattern)
if err != nil {
return nil, "", fmt.Errorf("%w: rule %q: %s", ErrInvalidRule, r.Name, err)
}
if re.MatchString("") {
// Such a pattern matches at every position and would replace the
// whole body with placeholders. Refuse it rather than destroy the
// capture.View on GitHub (pinned to 27d5a3981a)
Solutions
- Convert the rule to RuleTypeRegex with an equivalent pattern (e.g. JSONPath '$.user.email' -> a regex anchored on the serialized key \"email\"\s*:).
- Filter the rule set to RuleTypeRegex/RuleTypeBuiltin before calling Payload if the same list must serve multiple surfaces.
- Surface rule-type support at rule-authoring time (the validator surface the code notes is missing) so unsupported types are rejected at write time, not capture time.
Example fix
// before
rules := []redact.Rule{{Name: "user-email", Type: redact.RuleTypeJSONPath, Pattern: "$.user.email"}}
out, rep, err := redact.Payload(body, rules)
// after
rules := []redact.Rule{{Name: "user-email", Type: redact.RuleTypeRegex, Pattern: `"email"\s*:\s*"[^"]+"`}}
out, rep, err := redact.Payload(body, rules) Defensive patterns
Strategy: type-guard
Validate before calling
var supportedTypes = map[redact.RuleType]bool{
redact.RuleTypeBuiltin: true,
redact.RuleTypeRegex: true,
}
func onlySupported(rules []redact.Rule) []redact.Rule {
out := rules[:0]
for _, r := range rules {
if supportedTypes[r.Type] { out = append(out, r) }
}
return out
} Type guard
func isSupportedRuleType(t redact.RuleType) bool {
return t == redact.RuleTypeBuiltin || t == redact.RuleTypeRegex
} Try / catch
if _, _, err := redact.Payload(body, rules); err != nil {
if errors.Is(err, redact.ErrRuleUnsupported) {
// surface to rule author with the rule name/type from the message
}
} Prevention
- Keep one rules file per surface; don't share a JSONPath/header rule set with the regex-only redactor.
- Translate JSONPath rules to anchored regex equivalents at build time.
- Fail at rule-write time (validator/UI) rather than capture time — unsupported types are authoring errors.
When it happens
Trigger: compileOrgRules (via Payload) receives a rule list containing {Type: RuleTypeJSONPath} or {Type: RuleTypeHeader}, e.g. rules authored for a different redaction surface or copied from a config that assumed structured support.
Common situations: A shared redaction-rules config reused across services where only one supports JSONPath/header rules; a UI rule editor offering types this backend rejects; rules written against the roadmap rather than the shipped implementation.
Related errors
- %w: empty name
- %w: rule %q has an empty pattern
- %w: rule %q: %s
- cave_budget_denomination_ambiguous
- cave_budget_max_invalid
AI-assisted analysis of JuliusBrussee/caveman@27d5a3981a (2026-08-15).
Data as JSON: /api/errors/7d4a0040103d9a0f.
Report an issue: GitHub.