larksuite/cli · error

compile rule %q pattern: %w

Error message

compile rule %q pattern: %w

What it means

LoadConfig compiles each rule's Pattern as a Go regexp after parsing. If regexp.Compile fails, the error names the rule ID whose pattern is invalid. Go RE2 syntax differs from PCRE/JavaScript regex, so patterns valid elsewhere may fail here.

Source

Thrown at internal/security/contentsafety/config.go:49

	ID      string `json:"id"`
	Pattern string `json:"pattern"`
}

func LoadConfig(configDir string) (*Config, error) {
	path := filepath.Join(configDir, configFileName)
	data, err := vfs.ReadFile(path)
	if err != nil {
		return nil, fmt.Errorf("read content-safety config: %w", err)
	}
	var raw rawConfig
	if err := json.Unmarshal(data, &raw); err != nil {
		return nil, fmt.Errorf("parse content-safety config: %w", err)
	}
	rules := make([]rule, 0, len(raw.Rules))
	for _, r := range raw.Rules {
		compiled, err := regexp.Compile(r.Pattern)
		if err != nil {
			return nil, fmt.Errorf("compile rule %q pattern: %w", r.ID, err)
		}
		rules = append(rules, rule{ID: r.ID, Pattern: compiled})
	}
	return &Config{Allowlist: raw.Allowlist, Rules: rules}, nil
}

func EnsureDefaultConfig(configDir string, errOut io.Writer) error {
	path := filepath.Join(configDir, configFileName)
	if _, err := vfs.Stat(path); err == nil {
		return nil
	}
	if err := vfs.MkdirAll(configDir, 0700); err != nil {
		return fmt.Errorf("create config dir: %w", err)
	}
	data, err := json.MarshalIndent(defaultRawConfig(), "", "  ")
	if err != nil {
		return fmt.Errorf("marshal default config: %w", err)
	}

View on GitHub (pinned to 7fd6ef3c07)

Solutions

  1. Check the rule ID in the message and test the pattern with Go RE2 (e.g. https://regex101.com with the Go flavor)
  2. Rewrite lookarounds/backreferences using RE2-supported constructs or match broader and filter in code
  3. Escape unbalanced special characters ( ( [ ) properly
  4. Validate patterns before shipping by compiling them in a test

Example fix

// before
{"id": "ssn", "pattern": "(?<=\bseq)\d{9}"}  // lookbehind unsupported
// after
{"id": "ssn", "pattern": "\b\d{3}-\d{2}-\d{4}\b}"}
Defensive patterns

Strategy: validation

Validate before calling

for _, r := range rules {
	if _, err := regexp.Compile(r.Pattern); err != nil {
		return fmt.Errorf("rule %q: invalid pattern: %w", r.ID, err)
	}
}

Try / catch

config, err := contentsafety.LoadConfig(dir)
if err != nil {
	if strings.Contains(err.Error(), "compile rule") {
		// extract rule ID from message, fix or drop that rule in the config, retry
	}
	return err
}

Prevention

When it happens

Trigger: A rule in the content-safety config has a pattern with invalid RE2 syntax — e.g. unsupported constructs like lookbehind (?<=...), backreferences \1, or unbalanced parentheses/brackets.

Common situations: Copying regex from PCRE/JS sources with lookarounds or backreferences; hand-editing patterns and leaving an unescaped '(' or '['; patterns written for a different regex flavor.

Related errors


AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04). Data as JSON: /api/errors/0e8d7f62ff3a37b0. Report an issue: GitHub.