karatelabs/karate · error · ParserException

octal literals are not allowed in strict mode

Error message

octal literals are not allowed in strict mode

What it means

Strict-mode early error: the parser found an integer literal written with a legacy octal prefix, e.g. `0755` (or NonOctalDecimal like `08`/`09`). Legacy octal literals are forbidden in strict mode; use the `0o` prefix instead. Thrown at parse time, before execution.

Solutions

  1. Rewrite the literal with the modern octal prefix: `0755` becomes `0o755`
  2. Use a decimal literal instead if octal was not intended (`755`)
  3. Strip the leading zero for values like `08` -> `8`
  4. Compute the value explicitly if you need the octal interpretation: `parseInt('755', 8)`

Example fix

// before
var perms = 0755; // legacy octal
// after
var perms = 0o755;
Defensive patterns

Strategy: validation

Validate before calling

// flag legacy octal / leading-zero literals before parsing
const legacyOctal = /\b0[0-9]+\b/;
if (legacyOctal.test(src)) {
  throw new Error('script contains legacy octal literal (use 0o prefix)');
}

Try / catch

try {
  parseScript(src);
} catch (e) {
  if (String(e).includes('octal literals are not allowed')) {
    // rewrite literal with 0o prefix or decimal
  }
  throw e;
}

Prevention

When it happens

Trigger: Parsing any NUMBER token whose text starts with '0' followed by a digit 0-9, e.g. `var mode = 0755;` or `08` inside strict-mode code — the literal-length and char checks in the octal validator fire.

Common situations: Copying file-permission constants (`0755`, `0644`) from shell/POSIX examples into Karate JS; older scripts written before ES5 strict mode; dates like `08` typed with a leading zero.

Related errors


AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12). Data as JSON: /api/errors/1507873c50d85614. Report an issue: GitHub.

Appendix: source

Thrown at karate-js/src/main/java/io/karatelabs/parser/JsParser.java:1495

    /** Strict-mode early error for a legacy octal ({@code 0755}) or NonOctalDecimal
     *  ({@code 08} / {@code 09}) integer literal — any NUMBER whose text starts with
     *  {@code 0} immediately followed by a decimal digit. {@code 0x…} / {@code 0b…} /
     *  {@code 0o…} / {@code 0.…} / {@code 0e…} have a non-digit second char and a plain
     *  {@code 0} is length 1, so all are correctly excluded. */
    private static void checkLegacyOctalLiteral(Node litExpr) {
        if (litExpr.size() != 1) {
            return;
        }
        Node tok = litExpr.getFirst();
        if (!tok.isToken() || tok.token.type != NUMBER) {
            return;
        }
        String text = tok.getText();
        if (text.length() >= 2 && text.charAt(0) == '0') {
            char c = text.charAt(1);
            if (c >= '0' && c <= '9') {
                throw new ParserException("octal literals are not allowed in strict mode");
            }
        }
    }

    // CoverInitializedName early error (§12.2.6.1): a shorthand-with-default
    // (`IDENT = AssignmentExpression`) inside object-literal braces is only legal
    // when the surrounding `{...}` is refined as an ObjectAssignmentPattern /
    // ObjectBindingPattern; in a plain object literal it is a SyntaxError. The
    // parser accepts the cover form unconditionally in `object_elem()` (at parse
    // time it can't yet tell whether `{...}` is an assignment LHS / binding / arrow
    // param), so `earlyErrors` rejects it where pattern context never materializes.
    // That check and the pattern-context rest-element rules below are applied inline
    // by `earlyErrors`, which threads `inPattern` via `childInPatternContext`.

    /**
     * Spec early errors for {@code BindingRestElement} / {@code AssignmentRestElement}
     * inside an {@code ArrayBindingPattern} / {@code ArrayAssignmentPattern}:
     * <ul>

View on GitHub (pinned to a22eb90246)