Skip to content

Sass: @warn Directive

How to use Sass's @warn directive to issue non-fatal warnings with stack traces when users pass deprecated or invalid arguments to mixins and functions.

@warn Directive

When writing mixins and functions, you may want to discourage users from passing certain arguments or certain values. They may be passing legacy arguments that are now deprecated, or they may be calling your API in a way that's not quite optimal.

The @warn rule is designed just for that. It's written @warn <expression> and it prints the value of the expression (usually a string) for the user, along with a stack trace indicating how the current mixin or function was called. Unlike the @error rule, though, it doesn't stop Sass entirely.

$known-prefixes: webkit, moz, ms, o;

@mixin prefix($property, $value, $prefixes) {
  @each $prefix in $prefixes {
    @if not index($known-prefixes, $prefix) {
      @warn "Unknown prefix #{$prefix}.";
    }

    -#{$prefix}-#{$property}: $value;
  }
}

.tilt {
  // Oops, we typo'd "webkit" as "wekbit"!
  @include prefix(transform, rotate(15deg), wekbit ms);
}

and the generated style.css output:

.tilt {
  -wekbit-transform: rotate(15deg);
  -ms-transform: rotate(15deg);
  transform: rotate(15deg);
}

The exact format of the warning and stack trace varies from implementation to implementation. This is what it looks like in Dart Sass:

Warning: Unknown prefix wekbit.
    example.scss 6:7   prefix()
    example.scss 16:3  root stylesheet

When to use @warn

Use @warn when you want to alert developers without breaking the build. Typical scenarios include:

  • Deprecated APIs: A mixin or function argument is being phased out.
  • Suspicious values: An argument looks unusual but might still be valid.
  • Missing best practices: The user's choice works but is discouraged.
  • Unrecognized inputs: A value isn't in a known list (like the prefixes example above).
@mixin legacy-flexbox($display: flex) {
  @if $display == inline-flex {
    @warn "The inline-flex value is deprecated; use display: inline-flex directly.";
  }
  display: $display;
}

@warn vs @error vs @debug

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

Suppressing warnings in production

Warnings are meant for developers, not for end users. In a build pipeline you can suppress them by redirecting stderr or using your build tool's quiet mode. With the Sass CLI, redirect stderr to /dev/null (Unix) or NUL (Windows):

# Unix / macOS
sass input.scss output.css 2>/dev/null

# Windows
sass input.scss output.css 2>NUL

If you want to keep other errors but silence only @warn messages, most build tools (Webpack, Rollup, etc.) provide a logger or quietDeps option to filter warnings from specific dependencies.

Writing effective warnings

  • Be specific: say exactly what the issue is.
  • Show the value: interpolate the actual input so the developer can see what triggered the warning.
  • Suggest the fix: tell them what to do instead.
@mixin spacing($margin: 0, $padding: null) {
  @if type-of($margin) != "number" and type-of($margin) != "null" {
    @warn "$margin should be a number or null, but was `#{type-of($margin)}`.";
  }
  margin: $margin;
  padding: $padding;
}

Summary

  • @warn <expression> prints a message and stack trace but does not stop compilation.
  • Use @warn for deprecated APIs, suspicious values, or non-optimal usage that still produces valid CSS.
  • Unlike @error, CSS is still generated even if a warning is emitted.
  • Warnings appear in the build log; suppress them in production via your build tool or by redirecting stderr.
  • Write clear, actionable messages that show the value and suggest a fix.
Navigation