Sass @error Rule

Beginner
10 min read
Updated: Nov 2026
5 examples
Compiled CSS

Definition and Usage

The Sass @error rule is written @error <expression>;. It prints the value (usually a string) along with a stack trace showing how the current mixin or function was called, then stops compiling and reports failure to your build tool.

Use it when writing mixins and functions that take arguments: if types or formats are wrong, notify the user and refuse to continue. Soft tips belong in @warn; value inspection belongs in @debug.

Official pattern.

Per the Sass docs: guard mixin keywords early (for example only left / right) with an interpolated message that names the bad value.

Hard fail on purpose.

If continuing would emit broken or incomplete CSS, prefer @error over silently shipping wrong styles.

Write actionable messages.

Say what was wrong, what was received, and what is allowed — not a vague "Invalid argument."

Syntax

SCSS
@mixin reflexive-position($property, $value) {
  @if $property != left and $property != right {
    @error "Property #{$property} must be either left or right.";
  }

  $left-value: if($property == right, initial, $value);
  $right-value: if($property == right, $value, initial);

  left: $left-value;
  right: $right-value;

  [dir=rtl] & {
    left: $right-value;
    right: $left-value;
  }
}

.sidebar {
  @include reflexive-position(top, 12px);
}

Passing top prints an error and a stack that points at the include — no CSS is produced for that compile.

@error vs @warn vs @debug

Pick the right messaging at-rule:

At-ruleStops compile?Best for
@errorYesInvalid API usage; must not continue
@warnNoDeprecations and soft tips for API users
@debugNoInspecting values while developing

SCSS Examples

Valid calls show compiled CSS. Invalid calls show the compiler error (no CSS is produced). Open the output buttons to compare both paths.

Example 1 — Valid Mixin Call

When arguments pass the guard, styles compile normally.

SCSS
@mixin reflexive-position($property, $value) {
  @if $property != left and $property != right {
    @error "Property #{$property} must be either left or right.";
  }

  $left-value: if($property == right, initial, $value);
  $right-value: if($property == right, $value, initial);

  left: $left-value;
  right: $right-value;

  [dir=rtl] & {
    left: $right-value;
    right: $left-value;
  }
}

.sidebar {
  @include reflexive-position(left, 12px);
}

How It Works

  1. left is allowed, so the guard passes.
  2. @error never runs for this call.
  3. LTR values set left / right.
  4. RTL nest swaps the sides under [dir=rtl].

Example 2 — Invalid Mixin Call

Passing top triggers @error and stops the compile.

SCSS
@mixin reflexive-position($property, $value) {
  @if $property != left and $property != right {
    @error "Property #{$property} must be either left or right.";
  }

  $left-value: if($property == right, initial, $value);
  $right-value: if($property == right, $value, initial);

  left: $left-value;
  right: $right-value;
}

.sidebar {
  @include reflexive-position(top, 12px);
}

How It Works

  1. The guard rejects top.
  2. Sass prints the message and a stack trace.
  3. Compilation aborts — no CSS ships.
  4. Fix the include instead of debugging broken layout later.

Example 3 — Type Guard (Valid)

Assert a number, then use it in a calculation.

SCSS
@use "sass:meta";
@use "sass:math";

@function assert-number($value, $name: "value") {
  @if meta.type-of($value) != number {
    @error "#{$name} must be a number; got #{meta.type-of($value)} (#{$value}).";
  }
  @return $value;
}

.card {
  opacity: math.div(assert-number(80, "$opacity"), 100);
}

How It Works

  1. 80 is a number, so the assert returns it.
  2. math.div produces 0.8.
  3. Reusable helper keeps type checks in one place.
  4. Name the argument in the message for clearer call-site fixes.

Example 4 — Type Guard (Invalid)

A string fails the same assert with a detailed message.

SCSS
@use "sass:meta";

@function assert-number($value, $name: "value") {
  @if meta.type-of($value) != number {
    @error "#{$name} must be a number; got #{meta.type-of($value)} (#{$value}).";
  }
  @return $value;
}

.card {
  opacity: assert-number("eighty", "$opacity");
}

How It Works

  1. Type is string, so the guard fires.
  2. Message includes type and value for a fast fix.
  3. Stack points at the call site in the root stylesheet.
  4. No opacity CSS is emitted until the argument is fixed.

Example 5 — Unit & Range Checks

Accept unitless or % amounts only within 0–100.

SCSS
@use "sass:math";
@use "sass:meta";

@function clamp-percent($amount) {
  @if meta.type-of($amount) != number {
    @error "$amount must be a number.";
  }
  @if not math.is-unitless($amount) and math.unit($amount) != "%" {
    @error "$amount must be unitless or %; got #{$amount}.";
  }
  @if $amount < 0 or $amount > 100 {
    @error "$amount must be between 0 and 100; got #{$amount}.";
  }
  @return $amount;
}

.badge {
  --tint: #{clamp-percent(40%)};
  width: clamp-percent(50) * 1%;
}

How It Works

  1. Both calls pass type, unit, and range checks.
  2. Unitless 50 is scaled to 50% in CSS.
  3. Values like 120, -5%, or 10px would hit @error.
  4. Layered guards keep each failure message specific.

Edge Cases & Pitfalls

Most @error issues are vague messages, wrong severity, or validating too late.

message

Include the bad value

Interpolate with #{$value} and name allowed options. Vague "Invalid." messages waste time.

severity

Do not hard-fail soft advice

Deprecations and tips belong in @warn. Reserve @error for usage that must not continue.

order

Validate before emitting CSS

Put guards at the top of mixins/functions so bad calls never partial-emit styles.

scope

Focus on public APIs

Over-guarding private helpers can make internals brittle. Guard what callers actually pass.

Sass Support

@error is a core Dart Sass at-rule. Stack-trace formatting varies slightly by implementation and build tool; stopping the compile is consistent.

ImplementationStatus
Dart SassSupported (recommended)
LibSass / node-sassSupported (deprecated toolchain)
Ruby SassSupported (end-of-life)
BrowsersN/A — no CSS ships after @error

Prefer Dart Sass for new projects. SCSS and indented syntax both support @error.

Key Takeaways

  • Hard fail: @error prints a message + stack and stops the build.
  • Guard APIs in mixins/functions before emitting styles.
  • Interpolate bad values and name what is allowed.
  • Soft tips? Use @warn. Inspecting? Use @debug.

One line: @error refuses bad API usage loudly so broken CSS never ships.

Compile Notes

@error never reaches the browser. Conceptual flow:

flow.txt
1. Call a mixin / function with arguments
2. Run validation guards (@if + checks)
3. If invalid → @error prints message + stack
4. Sass stops compiling and reports failure
5. Fix the call site, then recompile

Frequently Asked Questions

It prints the value of an expression (usually a string) plus a stack trace, then stops compiling the stylesheet and reports a failure to your build tool.
Use it in mixins and functions to enforce your API: wrong types, out-of-range values, unsupported keywords, or missing required configuration.
@error stops compilation. @warn prints a warning and continues. Use @warn for soft deprecations; use @error when continuing would produce broken CSS.
No. If @error runs, no finished CSS is produced for that compile. Browsers never see @error.
Yes. Interpolate with #{$name} so callers see the bad value, for example @error "Got #{$property}, expected left or right."
Implementations vary. Dart Sass typically shows the failing call site and how you reached the mixin or function. Exact formatting depends on your Sass version and build system.

Next: Sass @warn Rule

Soft guidance and deprecations that keep compiling.

Sass @warn Rule →

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

8 people found this page helpful