ast-grep/ast-grep · error

RuleNotSpecified

RuleNotSpecified

Error message

RuleNotSpecified

What it means

Thrown from ScanWorker::try_new when no rules could be located: the CLI was invoked as `sg scan` without a --rule/-r flag, without --inline-rules, and without any rule file path or inline rule text. ast-grep requires at least one rule source to construct the scan worker.

Source

Thrown at crates/cli/src/scan.rs:324

struct ScanStdin {
  rules: Vec<RuleConfig<SgLang>>,
  // TODO: remove this
  error_count: AtomicUsize,
  max_diagnostics_shown: Option<usize>,
}
impl ScanStdin {
  fn try_new(arg: ScanArg) -> Result<Self> {
    let overwrite = RuleOverwrite::new(&arg.overwrite)?;
    let global_rules = Default::default();
    let rules = if let Some(path) = &arg.rule {
      read_rule_file(path, &global_rules).and_then(|configs| overwrite.process_configs(configs))?
    } else if let Some(text) = &arg.inline_rules {
      let configs = from_yaml_string(text, &global_rules)
        .with_context(|| EC::ParseRule("INLINE_RULES".into()))?;
      overwrite.process_configs(configs)?
    } else {
      return Err(anyhow::anyhow!(EC::RuleNotSpecified));
    };
    Ok(Self {
      rules,
      error_count: AtomicUsize::new(0),
      max_diagnostics_shown: arg.max_results.map(usize::from),
    })
  }
}

impl Worker for ScanStdin {
  fn consume_items<P: Printer>(
    &self,
    items: Items<P::Processed>,
    mut printer: P,
  ) -> Result<ExitCode> {
    printer.before_print()?;
    for item in items {
      printer.process(item)?;

View on GitHub (pinned to fc2b1530db)

Solutions

  1. Pass a rule: `sg scan -r my-rule.yml`
  2. Or provide YAML directly: `sg scan --inline-rules 'id: x; language: js; rule: {pattern: foo}'`
  3. Or create an `sgconfig.yml` with a `ruleDirs` entry and run from the project root
  4. Check shell quoting so the flags are not swallowed

Example fix

// before
sg scan ./src
// after
sg scan -r rules/no-console.yml ./src
Defensive patterns

Strategy: validation

Validate before calling

if (!ruleFile && !inlineRules && !fs.existsSync('sgconfig.yml')) throw new Error('sg scan needs -r, --inline-rules, or sgconfig.yml');

Try / catch

try { scan(args) } catch (e) { if (/RuleNotSpecified/.test(String(e))) { console.error('Provide -r <file> or --inline-rules'); process.exit(2); } throw e }

Prevention

When it happens

Trigger: Calling `sg scan` with neither `--rule <path>`, `--inline-rules <yaml>`, nor a rule file argument such that both `arg.rule_file` and `arg.inline_rules` are None in try_new.

Common situations: Forgetting -r when scanning ad hoc; running scan from a directory without sgconfig.yml while relying on implicit rule discovery; CI scripts dropping the rule flag during refactoring.

Understand the failure class

Background: "X is required", "must be set", "cannot be empty": the missing-required-config error family, from Vertex AI project/location to WeChat keys — this error's family across 18 libraries.

Related errors


AI-assisted analysis of ast-grep/ast-grep@fc2b1530db (2026-09-05). Data as JSON: /api/errors/cfd9c6902fd282e9. Report an issue: GitHub.