Skip to content

@debug, @warn, and @error

Sass provides three diagnostic at-rules for different situations: @debug for development-time inspection, @warn for non-fatal cautionary messages, and @error for stopping compilation entirely on invalid input. This lesson covers when to use each.

Three Levels of Diagnostic Messages

@debug prints a value to the console during compilation without stopping anything, ideal for quickly inspecting an intermediate value. @warn prints a message but lets compilation continue, ideal for deprecation notices. @error prints a message and immediately halts compilation, ideal for genuinely invalid input that must be fixed.

@debug "Computed width: #{$width}";
@warn "This mixin is deprecated, use new-mixin() instead.";
@error "Invalid size: #{$size}. Expected sm, md, or lg.";

Each rule serves a different severity level, from harmless inspection to a hard stop that prevents the file from compiling at all.

Diagnostic Rule Syntax

@debug expression;
@warn expression;
@error expression;
  • All three accept any Sass expression, typically a string built with interpolation.
  • @debug and @warn do not stop compilation; @error does.
  • Messages appear in the terminal or build tool output where the Sass compiler runs.
  • @error can be called from inside a function or mixin to validate its own arguments.

@debug / @warn / @error Cheatsheet

Choosing the right diagnostic rule for a given situation.

Rule Stops Compilation? Best For
@debug No Quick, temporary inspection of a computed value
@warn No Deprecation notices, non-fatal cautionary messages
@error Yes Invalid arguments or genuinely unrecoverable states

@debug for Quick Inspection

@debug is the Sass equivalent of a console.log() for quickly checking what an expression actually evaluates to during development. Remove or comment out @debug statements before shipping, they're a development-time tool only.

@each $key, $value in $breakpoints {
  @debug "#{$key}: #{$value}";
}

@warn for Deprecation Notices

@warn is ideal inside a shared library or design system when renaming or removing a mixin, it lets existing consumers keep working while nudging them toward the replacement before you remove the old one entirely.

@mixin old-button-style {
  @warn "old-button-style() is deprecated, use button-variant() instead.";
  padding: 0.5rem 1rem;
}

@error for Argument Validation

@error is the right tool whenever continuing compilation would produce silently broken CSS. Stopping immediately with a clear message is far better than shipping a subtly wrong stylesheet to production.

@function spacing($key) {
  $valid: sm, md, lg;
  @if not index($valid, $key) {
    @error "spacing() expected one of #{$valid}, got '#{$key}'.";
  }
  @return map.get($spacer-map, $key);
}

Common Mistakes

  • Leaving @debug statements in committed code long after the inspection they were added for is done.
  • Using @warn for a genuinely invalid state that should stop compilation instead, letting broken CSS through silently.
  • Writing a vague @error message ("invalid input") instead of including the actual invalid value and the expected options.
  • Forgetting these messages only appear in the compiler's terminal output, not in the browser or DevTools.

Key Takeaways

  • @debug prints a value for quick, temporary inspection without stopping compilation.
  • @warn communicates a non-fatal issue, ideal for deprecation notices in shared code.
  • @error halts compilation immediately, the right choice for genuinely invalid input.
  • Clear, specific error messages (including the actual bad value) save significant debugging time for consumers of your mixins and functions.

Pro Tip

Write every @error message as if a stranger will read it with zero context, include the function or mixin name, the invalid value received, and the valid options expected, it turns a frustrating debugging session into a thirty-second fix.