Skip to main content

Rule Errors

Each problem in a version 2 .rules file has one error code. The tool shows the code in square brackets. Use the code and the hint to fix the rule. For the grammar, see Rule Syntax.

Error format​

<file>:<line>[:<col>]: rule "<id>": <message> [<CODE>]. Hint: <how to fix it>

Example:

.sigmashake/rules/egress.rules:9: rule "egress-example": a rule with ELSE IF or ELSE needs END before } [V2_MISSING_END]. Hint: write END on its own line after the last branch

The rule "<id>": part is absent for a problem outside a rule, such as a data block.

What happens to an invalid rule​

An invalid rule is not loaded. The rest of the file still loads. Each skipped rule or data block has one reason. The reason shows in these places:

  • ssg lint, and ssg lint --json for a machine-readable form
  • ssg rule sync
  • ssg status
  • The Rules page of the dashboard
  • The SessionStart banner

The write paths refuse an invalid rule before it reaches disk. These paths are save, inbox, import, and ssg new.

A bad data block is skipped. Each rule that uses its name then fails with V2_DATA_UNKNOWN_NAME.

Some problems skip the whole file, so the file loads no rule:

  • A line outside every block, such as a stray line.
  • A header that cannot be read.
  • More than 64 bad blocks in one file.

When a file has a skipped rule, the DB rows of that file stay until the file is fixed. Fix the reported rule, then run ssg lint again.

Codes for files and rules​

CodeMeaningFix
RULE_SYNTAXA line does not match the grammar. The code also covers the CONTEXT, CATEGORY, TAG and severity checks, and any error with no exact code.Read the message and the hint. Check the spelling of the keyword.
V2_EXPECTED_RULEA line at file scope is neither a rule nor a data block.Start a rule with rule <id> {. Start a data block with set, domains, prefixes or map.
V2_UNTERMINATED_RULEA rule has no closing }.Add } after the last line of the rule.
V2_AMBIENT_HAS_CONDITIONAn AMBIENT rule has an IF or OR condition.Remove the conditions, or remove AMBIENT. Ambient rules never gate a tool call.
V2_DUPLICATE_DIRECTIVEA directive appears twice in one branch.Keep one copy in each branch. A branch ends at ELSE IF, ELSE or END.
V2_TOO_COMPLEXThe rule expands to too many OR and AND groups. The file has more than 8192 groups or 65536 conditions in total, shared by all its rules. The rules of the file reference more than 16 MiB of data, because each rule counts a copy of each data block that it uses.Split the rule, or use fewer OR and AND groups. For the data limit, use fewer rules with a big data block, or a smaller block.
V2_NESTING_TOO_DEEPThe condition has more than 16 levels of parentheses.Flatten the condition, or split the rule.

Codes for regex patterns​

These codes apply to the pattern of each REGEX and LINE_REGEX condition, in version 1 files and in version 2 files.

CodeKindMeaningFix
RULE_REGEX_REJECTEDErrorThe regex engine cannot run the pattern. The message shows the reason from the engine. A lookbehind such as (?<=a)b, an atomic group, an inline flag such as (?i), a pattern of more than 500 bytes, and a group that has a quantifier inside it and a quantifier after it are examples. The rule fails secure: a block rule always fires, and an allow rule never fires.Write the pattern in the syntax that the engine reads. Shorten it. Use (?= or (?! for a lookahead.
RULE_REGEX_QUANTIFIED_ALTERNATIONError or warningA quantifier follows a group that has an alternation, for example (a|b)+. The flat form matches every input. A nested form is a warning in version 1 files, and an error in version 2 files.Write the alternatives as separate IF and OR conditions.
RULE_REGEX_DOUBLED_QUANTIFIERWarningA repeat operator follows another repeat operator, for example a++ or a**. The engine reads the second operator as a literal character. The rule still loads.Write \+ or \* if you mean the character itself. If you do not, remove the second operator.

Codes for data blocks​

CodeMeaningFix
V2_DATA_SYNTAXA data block has a syntax error. The block has no {, is not closed, has an unclosed string, has text after }, or uses = outside a map.Write set NAME { "entry" }. Close the block with }. Write a map entry as "key" = "value".
V2_DATA_BAD_NAMEThe data name does not match the name rule.Start the name with a lowercase letter. Use lowercase letters, digits and _ only.
V2_DATA_REDECLAREDA data name is declared twice in one file.Keep one block for each name. Or choose another name.
V2_DATA_EMPTYA data block has no entries.Add an entry, or delete the block.
V2_DATA_TOO_LARGEA data block has more than 4096 entries, or the data blocks of one file hold more than 2 MiB of entry text.Split the data. For a long list, use a threat feed. For the 2 MiB limit, remove entries, or keep the long list outside the rules file.
V2_DATA_TOO_MANY_BLOCKSA file has more than 64 data blocks.Merge the blocks, or split the file.
V2_DATA_BAD_ENTRYAn entry fails the check for its kind, or it is longer than 512 bytes.Follow the hint. A domain is a plain host name. A prefix is an absolute path. Other entries are non-empty strings of at most 512 bytes.
V2_DATA_DUPLICATE_ENTRYAn entry appears twice after it is normalized.Delete the second entry.
V2_DATA_UNKNOWN_NAMEA condition uses @name, and no block above the rule declares that name.Declare the block above the rule.
V2_DATA_KIND_MISMATCHThe operator needs a different kind of block.Use set for IN, domains for HOST_IN, prefixes for UNDER and map for MAP.

Codes for branches and decisions​

CodeMeaningFix
V2_TOO_MANY_BRANCHESA rule has more than 16 branches.Use a map for a long table, or split the rule.
V2_ELSE_WITHOUT_IFAn ELSE or END has no IF above it.Write IF <condition> first.
V2_BRANCH_AFTER_ELSEA branch follows ELSE.Make ELSE the last branch. Put ELSE IF branches above it.
V2_IF_IN_LATER_BRANCHAn IF appears after the first branch.Start the next branch with ELSE IF <condition>.
V2_BRANCH_NO_CONDITIONA branch that is not ELSE has no condition.Start the branch with IF <condition>.
V2_BRANCH_NO_DECISIONA rule with several branches has a branch with no decision line.Add a decision line, such as DENY execution.
V2_MISSING_ENDA rule has ELSE IF or ELSE, and no END before }.Write END on its own line after the last branch.
V2_AFTER_ENDA line follows END and is not }.Move the line above END, or into a new rule.
V2_MISSING_MESSAGEA branch or a rule has no MESSAGE.Add MESSAGE "text".
V2_MISSING_PROMPTAn ASK branch has no PROMPT.Add PROMPT "question".
V2_MISSING_SUBSTITUTEA FORCE branch has no SUBSTITUTE.Add SUBSTITUTE "command".
V2_MAP_OPERATOR_INVALIDA data operator follows MAP. This includes OWNED_EGRESS and OWNED_EGRESS_PIPE_SHELL.Use a content operator after MAP, such as EQUALS, STARTS_WITH, CONTAINS or REGEX.