Pular para o conteúdo
Cursos

DevClub

LógicaFront-endBack-endMobile

IA Club

IA na prática
Estudar programaçãoEstudar IA
Erro resolvidoIntermediáriocódigo testado

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.

Rodolfo Mori5 min de leitura

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:

css
.button { color: $brand; }
Error: Undefined variable. ╷ 1 │ .button { color: $brand; } │ ^^^^^^ ╵ - 1:18 root stylesheet

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:

css
// _tokens.scss
$brand: #6d28d9;

// app.scss
@use "tokens";
.button { color: $brand; }
Error: Undefined variable. ╷ 2 │ .button { color: $brand; } │ ^^^^^^ ╵ app.scss 2:18 root stylesheet

Com @use, o nome correto é tokens.$brand. O namespace deriva do arquivo e pode ser renomeado com as.

css
@use "tokens";
.button { color: tokens.$brand; }
.button { color: #6d28d9; }

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:

css
// _tokens.scss
$brand: #6d28d9;

// card.scss
.card { border-color: tokens.$brand; }
Error: There is no module with the namespace "tokens". ╷ 1 │ .card { border-color: tokens.$brand; } │ ^^^^^^^^^^^^^ ╵ card.scss 1:23 root stylesheet

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:

css
.card {
  $local: #6d28d9;
  color: $local;
}
.button { color: $local; }
Error: Undefined variable. ╷ 5 │ .button { color: $local; } │ ^^^^^^ ╵ - 5:18 root stylesheet

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:

css
// _tokens.scss
$_secret: #111827;

// app.scss
@use "tokens";
.secret { color: tokens.$_secret; }
Error: Private members can't be accessed from outside their modules. ╷ 2 │ .secret { color: tokens.$_secret; } │ ^^^^^^^^^^^^^^^ ╵ app.scss 2:18 root stylesheet

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:

css
@import "tokens";
.button { color: $brand; }
DEPRECATION WARNING [import]: Sass @import rules are deprecated and will be removed in Dart Sass 3.0.0.

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.

text
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.

  • sass
  • erro
  • undefined variable
  • use
  • escopo
  • namespace

Perguntas frequentes

Undefined variable significa que o arquivo não existe?
Não. A mensagem literal aparece ao esquecer o namespace ou sair do escopo. Módulo não carregado e membro privado recebem diagnósticos próprios.
Posso resolver usando @use as *?
Pode tornar o nome global, mas recria colisões. Prefira o namespace do módulo, como tokens.$brand.
Por que funcionava com @import?
@import colocava membros públicos no escopo global. @use isola o módulo e exige namespace por padrão.

Dúvidas e comentários

Travou em algum passo? Pergunte aqui — a equipe e outros alunos respondem.

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

  1. Sass — Variables and scope — sass-lang.com
  2. Sass — @use — sass-lang.com
  3. Sass — Private members — sass-lang.com

Continue por aqui