Error: Undefined variable no Sass: 4 causas e a correção
As quatro situações que produzem esse erro no Dart Sass, cada uma reproduzida no terminal, com a linha exata que o compilador aponta.
Error: Undefined variable significa que, naquele ponto e naquele módulo, o
Sass não encontra o nome pedido. Namespace esquecido e escopo local produzem
essa mensagem literal. Dependência não carregada e membro privado são problemas
próximos, mas o compilador usa diagnósticos mais específicos para eles.
Os quatro diagnósticos foram reproduzidos com Dart Sass 1.103.1. Para seguir o erro, leia primeiro mensagem, trecho, acentos e arquivo — não comece movendo declarações ao acaso.
A mensagem completa, do jeito que o compilador imprime
Este é o caso mínimo:
.button { color: $brand; }O status do processo foi 65. Nenhum CSS utilizável foi produzido na saída padrão. Se o comando grava num arquivo, Dart Sass pode escrever uma folha de erro para desenvolvimento; o terminal continua sendo a fonte principal.
Lendo o traço: ╷, linha e acento circunflexo
╷ abre o recorte. 1 │ é a linha. ^^^^^^ cobre $brand, exatamente o token
que não pôde ser resolvido. 1:18 informa linha e coluna. “root stylesheet” é o
ponto de entrada; numa cadeia de módulos, a pilha mostra arquivos intermediários.
Não leia o acento como local da causa definitiva. Ele marca onde o compilador percebeu o problema. A declaração ausente pode estar em outro arquivo ou presa num escopo fechado.
Causa 1: migrou para @use e esqueceu o namespace
_tokens.scss declara $brand, e a entrada carrega o módulo. Mesmo assim, a
referência global falha:
// _tokens.scss
$brand: #6d28d9;
// app.scss
@use "tokens";
.button { color: $brand; }Com @use, o nome correto é tokens.$brand. O namespace deriva do arquivo e
pode ser renomeado com as.
@use "tokens";
.button { color: tokens.$brand; }Evite as * só para manter o estilo antigo. O prefixo mostra a origem e impede
duas bibliotecas de disputar $brand. A aula de @use e
@forward detalha a migração.
Causa 2: o partial não foi carregado neste arquivo
Cada módulo tem escopo próprio. Outro arquivo ter usado tokens não torna a variável global para todos. Esta entrada esqueceu a dependência:
// _tokens.scss
$brand: #6d28d9;
// card.scss
.card { border-color: tokens.$brand; }Este caso não imprime Undefined variable: ele para antes, porque o namespace
tokens nem sequer existe na entrada.
Adicione @use "tokens"; no arquivo que consome o módulo. Não dependa de um
@use feito em outra folha: isolamento é parte do contrato moderno.
Causa 3: a variável está presa dentro de um bloco
Variáveis declaradas numa regra são locais. $local funciona dentro de .card
e deixa de existir depois:
.card {
$local: #6d28d9;
color: $local;
}
.button { color: $local; }Se o valor é token compartilhado, declare no topo do módulo. Se pertence ao
componente, mantenha o uso no bloco. Não aplique !global automaticamente; ele
cria estado compartilhado e esconde a fronteira.
Causa 4: o membro é privado e não sai do módulo
Nomes iniciados por _ ou - são privados. O módulo existe e o namespace está
certo, mas o contrato bloqueia acesso externo:
// _tokens.scss
$_secret: #111827;
// app.scss
@use "tokens";
.secret { color: tokens.$_secret; }Também aqui a mensagem não é Undefined variable: o módulo foi carregado e o
Sass reconheceu o membro, mas bloqueou o acesso por privacidade.
Se o valor faz parte da API, renomeie para público conscientemente e documente. Se é detalhe interno, crie uma função ou mixin público que ofereça o comportamento sem expor o token.
O mesmo arquivo que compilava com @import
O código antigo parece funcionar porque @import injeta $brand no escopo
global:
@import "tokens";
.button { color: $brand; }More info and automated migrator: https://sass-lang.com/d/import
╷ 1 │ @import “tokens”; │ ^^^^^^^^ ╵ - 1:9 root stylesheet
.button { color: #6d28d9; }
Trocar somente a primeira linha por @use muda o contrato. A migração correta
troca também cada referência para tokens.$brand, tokens.mixin() ou
tokens.function().
Os primos: Undefined mixin e Undefined function
O mesmo raciocínio vale para outros membros. @include button após @use "components" deve virar @include components.button; uma função própria
precisa do namespace. Primeiro confirme carga, depois namespace, escopo e
privacidade.
Undefined variable → tokens.$name
Undefined mixin → @include tools.name
Undefined function → tools.name(...)A categoria do erro muda; a árvore de diagnóstico permanece.
Blindar o projeto com um contrato de tokens
Centralize tokens públicos, marque configuráveis com !default, mantenha
helpers privados e reexporte a API com @forward show. Assim, um nome ausente é
erro de contrato, não caça ao import global.
Inclua uma folha de contrato pequena que consuma cada membro público. Ela deve carregar o ponto de entrada do pacote, ler variáveis, chamar funções e incluir mixins. Se uma refatoração deixar de encaminhar um membro, essa folha falha no CI antes de uma aplicação distante. É um teste barato para a superfície pública.
Padronize ainda os aliases de módulos. Se uma pasta usa @use "tokens" as t e
outra usa as design, o erro continua corrigível, mas a busca fica fragmentada.
O namespace padrão costuma ser suficientemente curto e documenta o arquivo.
Reserve alias para colisão real ou nome de pacote excessivamente longo.
Ao diagnosticar, anote o ponto de entrada usado no comando. Compilar app.scss
pode carregar uma árvore diferente de admin.scss; um token disponível em uma
entrada não prova que está disponível na outra. Rode exatamente o arquivo que
falhou no build e mantenha o caminho na mensagem reproduzida.
Adote uma checagem no CI que compile todas as entradas com warnings visíveis. Ao mover token, publique alias temporário ou uma mudança de versão; não deixe centenas de consumidores descobrir a remoção isoladamente.
Por fim, evite “corrigir” copiando o valor literal para o componente. O erro some, mas o token se divide em duas fontes da verdade. Resolva a dependência ou assuma explicitamente que o componente deixou de seguir o contrato; as duas decisões são revisáveis, enquanto uma cópia silenciosa não é.
Para revisar escopo e !default, volte a variáveis no
Sass. O guia de
Sass conecta esse erro à arquitetura de módulos e à ordem de
estudo.
Perguntas frequentes
Undefined variable significa que o arquivo não existe?
Posso resolver usando @use as *?
Por que funcionava com @import?
Dúvidas e comentários
Travou em algum passo? Pergunte aqui — a equipe e outros alunos respondem.
Entrar para perguntarÉ o mesmo login gratuito dos cursos.
Nenhuma dúvida por aqui ainda — a primeira pode ser a sua.
Todo o código deste artigo foi executado em Dart Sass 1.103.1 (dart2js 3.13.1), Node 26.3.0, macOS, e as saídas exibidas são as reais — como produzimos este conteúdo.
Fontes consultadas
- Sass — Variables and scope — sass-lang.com
- Sass — @use — sass-lang.com
- Sass — Private members — sass-lang.com


