Skip to content

Sass: @error Directive

How to use Sass's @error directive to validate inputs, display custom error messages, and halt compilation with stack traces for debugging mixins and functions.

@error Directive

@error, which is written @error <expression>, prints the value of the expression (usually a string) along with a stack trace indicating how the current mixin or function was called.

Once the error is printed, Sass stops compiling the stylesheet and tells whatever system is running it that an error occurred.

Example:

@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);
  //       ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  // Error: Property top must be either left or right.
}

The exact format of the error and stack trace varies from implementation to implementation, and can also depend on your build system. This is what it looks like in Dart Sass when run from the command line:

Error: "Property top must be either left or right."
  ╷
3 │     @error "Property #{$property} must be either left or right.";
  │     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  ╵
  example.scss 3:5   reflexive-position()
  example.scss 19:3  root stylesheet

When to use @error

Use @error to fail fast when a function or mixin receives invalid input. Typical use cases include:

  • Validation: Enforce allowed values, types, or ranges.
  • Required arguments: Fail if a mandatory argument is missing or null.
  • Boundary checks: Reject out-of-range numeric inputs.
  • Impossible states: Catch combinations that can't produce valid CSS.
@mixin spacing($margin, $padding: null) {
  @if $margin == null {
    @error "$margin cannot be null.";
  }

  margin: $margin;
  @if $padding != null {
    padding: $padding;
  }
}

.button {
  @include spacing(null);
  // Error: $margin cannot be null.
}

@error vs @warn vs @debug

Sass provides three directives for runtime messages. Choose the right one for the situation:

Directive Halts compilation Visible in output CSS Typical use case
@error ✅ Yes ❌ No Invalid input: compilation cannot continue
@warn ❌ No ❌ No Suspicious or deprecated usage: continue but warn
@debug ❌ No ❌ No Development tracing: print variable values to the console

@warn example

@mixin legacy-grid($columns: 12) {
  @warn "The legacy-grid mixin is deprecated. Use the new grid() mixin instead.";
  // … legacy implementation
}

@debug example

@mixin flex-row($gap) {
  @debug "flex-row received gap: #{$gap}";
  display: flex;
  gap: $gap;
}

Writing clear error messages

A good error message helps developers fix the issue quickly:

  • State the problem: what went wrong.
  • Show the value: interpolate the actual input so the caller can see what they passed.
  • Suggest a fix: if possible, hint at the correct value or type.
@function pow($base, $exponent) {
  @if not type-of($base) == "number" or not type-of($exponent) == "number" {
    @error "pow() requires numeric arguments; got base: #{type-of($base)}, exponent: #{type-of($exponent)}.";
  }
  @return $base ** $exponent;
}

The message explicitly says what was wrong and what was received, making it easy to correct.

Summary

  • @error <expression> prints the expression and stops compilation immediately.
  • Use @error for input validation and impossible states: fail fast so bad CSS doesn't leak into the build.
  • Sass prints a stack trace showing exactly where the error was raised and how the mixin/function was called.
  • For non-fatal issues, use @warn to log a warning or @debug to print debug info without stopping the compiler.
  • Write error messages that are descriptive, show the actual value, and hint at the fix.
Navigation