Item UGC rejeitado na moderação: como achar a causa real
Seu acessório voltou como rejeitado e a mensagem da moderação não diz o que estava errado. Este texto separa as cinco causas possíveis em ordem de custo e entrega um validador que roda no Studio antes de você queimar a próxima taxa de upload.
Rascunho assistido por IA, revisado, testado e editado por um humano antes de publicar. Ver Política Editorial. · Revisado por Gustavo Cantino, 05/09/2026 Política Editorial

Seu item UGC foi rejeitado, chegou uma notificação genérica falando em violação das Regras da Comunidade e você continua sem saber o que exatamente estava errado no acessório. Isso não é falha do sistema: o mesmo texto padrão cobre cinco causas diferentes — nome, descrição, textura, malha e categoria — e a moderação não detalha qual delas pegou. Dá pra eliminar as cinco em ordem, da mais barata pra mais cara, e chegar na culpada em uns 15 minutos, sem reenviar às cegas e sem torrar taxa de upload no chute.
Sua mensagem de rejeição não diz o motivo, e isso custa Robux
O prejuízo aqui é medido em Robux, não em tempo. A taxa de publicação do acessório é cobrada no momento em que você confirma o upload no Creator Dashboard, não quando o item é aprovado — item recusado é taxa queimada. Com o pacote de 800 Robux custando na casa dos R$ 40 no varejo brasileiro, cada tentativa perdida sai por perto disso. Quem sobe uma leva de cinco itens e leva três rejeições jogou fora o preço de um jogo indie por causa de uma palavra na descrição.
Tem um custo que não aparece em lugar nenhum: histórico. Rejeição de moderação não é só "não passou", é um registro na sua conta. Acumular rejeições seguidas do mesmo tipo — principalmente as que a Roblox classifica como tentativa de burlar filtro — é o caminho mais rápido pra perder o acesso à publicação de itens de avatar. Ninguém avisa que você está perto do limite; você descobre quando o botão some.
Antes de investigar, separe dois eventos que quase todo mundo mistura:
Erro de validação no upload. É a mensagem técnica que aparece na hora, ainda na tela de publicação: malha com triângulos demais, textura acima do tamanho permitido, attachment ausente, mais de um MeshPart dentro do Handle. Aqui nada foi moderado — o item nem entrou na fila. É problema de arquivo, resolve no Blender.
Rejeição de moderação. O item foi aceito tecnicamente, entrou na fila e voltou marcado como rejeitado na aba Creations, de minutos a alguns dias depois. Aqui um humano ou um classificador olhou o conjunto: imagem renderizada, nome, descrição e a malha. É deste caso que este texto trata.
Se o que você recebeu foi a primeira coisa, pare de reescrever a descrição — não é isso. Se foi a segunda, siga a triagem abaixo na ordem.
Triagem em 6 passos, do mais barato pro mais caro
1. Nome e descrição. É a causa mais comum e a mais boba. Nome de personagem de outra empresa (Naruto, Sonic, Goku, Mickey), marca real (Nike, Gucci, Supreme), nome de rede social, link, arroba, menção a "free", "grátis", "Robux", "promo code", qualquer coisa que soe a promessa comercial fora da plataforma. Escrever com números no lugar de letras — N4ruto, G0ku — é pior do que escrever certo: vira tentativa deliberada de burlar filtro, que é uma infração mais grave que a original. Reescreva o nome como descrição física do objeto: "Bandana Laranja com Placa de Metal" passa onde "Naruto Headband" não passa.
2. Textura. Texto legível dentro da textura é o segundo motivo mais frequente. Qualquer palavra escrita na imagem — inclusive sua assinatura, seu @ ou o nome do seu grupo — é lida como texto não moderado e derruba o item. Some a isso: logos reconhecíveis, símbolos políticos ou religiosos controversos, sangue, e o clássico desenho escondido num canto do UV que ninguém vai ver no jogo. A moderação olha o arquivo de textura, não o render bonito. Se você comprou ou baixou a textura, revise pixel a pixel o que veio junto.
3. Malha. Formas que reproduzem anatomia humana de forma realista, armas de fogo realistas, itens que na prática viram um avatar inteiro em vez de um acessório, e malha invisível ou com transparência alta usada pra esconder o volume real. Transparência acima de zero num Handle de acessório é sinal vermelho automático pra qualquer revisor: a leitura padrão é que você está escondendo alguma coisa.
4. Categoria e attachment. Publicar um chapéu na categoria de acessório de rosto, ou subir uma peça de layered clothing sem cage, aparece pra quem revisa como item mal classificado — e mal classificado é motivo de recusa. O nome do Attachment dentro do Handle é o que define onde o item encaixa, e ele precisa ser exatamente um dos nomes que a Roblox reconhece. Isto aqui é o erro que mais vejo em item de quem está começando:
-- errado: nome livre no attachment
local a = Instance.new("Attachment")
a.Name = "Chapeu" -- a Roblox não reconhece, o item encaixa torto ou é recusado
a.Parent = workspace.Accessory.HandleOs nomes válidos são fixos: HatAttachment, HairAttachment, FaceFrontAttachment, NeckAttachment, FrontAttachment, BackAttachment, WaistFrontAttachment, WaistBackAttachment, WaistCenterAttachment, LeftShoulderAttachment e RightShoulderAttachment. Um Handle, um Attachment, nome exato, sem sobrar.
5. Semelhança com item que já existe. Se a sua malha é muito parecida com a de outro criador — porque você partiu do mesmo template, do mesmo pack do Sketchfab ou porque literalmente copiou — o item pode voltar por denúncia de propriedade intelectual, mesmo dias depois de aprovado. Item que já está à venda e some do catálogo do nada costuma ser isso.
6. Histórico da conta. Se os passos de 1 a 5 estão limpos e ainda assim tudo que você sobe volta, o problema pode não estar no item. Conta com strikes recentes entra numa fila mais rígida. Nesse caso a saída é parar de subir por alguns dias, resolver as moderações abertas no suporte e voltar com um item obviamente inofensivo pra testar o canal.
Rodar essa triagem na mão em cada item é o que consome os 15 minutos. O que dá pra automatizar é a parte chata — estrutura, tamanho, transparência e palavras de risco no texto — e é isso que o script abaixo faz.
O validador que roda antes de você gastar Robux
O artefato é um Script comum que você cola em ServerScriptService. Ele lê tudo que estiver dentro de uma pasta chamada UGC_Check em ServerStorage, e para cada Accessory faz sete verificações: existe Handle, existe exatamente um Attachment com nome reconhecido, o tamanho cabe na caixa daquele ponto de encaixe, a malha não está transparente, não tem Script nem Decal escondido dentro, existe textura ou SurfaceAppearance, e o nome mais a descrição não batem com a lista de termos de risco.
A descrição não mora no modelo — ela mora no site. Por isso o script lê um atributo chamado Descricao no próprio Accessory. Antes de rodar, selecione o item, vá em Properties, adicione o atributo Descricao como string e cole ali o texto exato que você vai colar no Creator Dashboard. É esse texto que precisa passar, não uma versão aproximada.
Pra usar: cole o script, crie a pasta, arraste os acessórios pra dentro, aperte Play e leia o Output. Linha com REPROVA é bloqueio — não suba. Linha com ATENCAO é decisão sua. Zero linhas significa que a estrutura está limpa e sobrou o que o script não consegue ver: contagem de triângulos e o conteúdo visual da textura, que continuam sendo trabalho de olho humano no Blender.
Os limites de caixa e a lista de termos ficam no topo do arquivo, editáveis. Confirme os valores atuais na documentação de especificação de acessórios antes de rodar em cima de uma leva grande: a Roblox mexe nesses números sem avisar, e um validador desatualizado é pior que nenhum, porque te dá confiança falsa.
O erro caro: reenviar o mesmo item até passar
O reflexo depois da rejeição é subir de novo. Trocar uma letra no nome, apertar publicar, torcer. É o pior movimento possível por dois motivos.
Primeiro, cada reenvio paga a taxa outra vez. Três tentativas no escuro custam três vezes o preço de publicação e não te dão nenhuma informação nova, porque a mensagem de retorno continua sendo a mesma frase genérica. Você está pagando pra receber o mesmo texto.
Segundo, e mais grave: reenvio repetido do mesmo conteúdo recusado é lido como tentativa de forçar passagem. Isso escala a punição de "item rejeitado" pra "conta moderada", e conta moderada tira seu acesso à publicação de itens de avatar por um período — ou de vez, se já houver histórico.
O caminho certo depois de uma rejeição é: primeiro rodar a triagem e o validador, segundo mudar de verdade a coisa que você identificou (nome inteiro, textura regravada, malha remodelada — não uma letra), e terceiro, se você tem certeza de que o item está limpo, abrir um pedido de revisão no suporte em vez de reenviar. Um item por vez, e só depois que o anterior teve resposta. Se você não consegue apontar qual das cinco causas era, você não corrigiu nada — só mexeu.
O que medir na próxima leva
Abra uma planilha com cinco colunas: nome do item, data e hora do publish, data e hora da resposta, resultado, e a causa que você identificou depois. Trinta itens nessa planilha valem mais que qualquer palpite de fórum.
Duas métricas saem dela. A primeira é sua taxa de aprovação por leva — se ela está abaixo de 80%, o problema é sistêmico no seu pipeline, provavelmente textura ou nomenclatura, e não azar de moderação. A segunda é o tempo médio de resposta: se você tem um baseline de quanto costuma demorar, consegue saber quando um item está travado de verdade e vale abrir suporte, em vez de esperar mais uma semana sem motivo.
Com trinta linhas você também descobre qual das cinco causas é a sua causa. Quase todo criador tem uma dominante, e ela quase nunca é a que ele imaginava. Quando você souber qual é a sua, adicione a verificação correspondente na lista de termos do validador e ela nunca mais volta.
Artefato pronto pra usar
--!strict
--[[
Validador de item UGC antes do upload.
COMO USAR
1. Cole este Script em ServerScriptService.
2. Crie uma pasta chamada "UGC_Check" dentro de ServerStorage.
3. Arraste pra dentro dela os Accessory que voce vai publicar.
4. Em cada Accessory, adicione um atributo string chamado "Descricao"
com o texto EXATO que voce vai colar no Creator Dashboard.
5. Aperte Play (F5) e leia o Output.
REPROVA = nao suba assim.
ATENCAO = decisao sua, mas revise.
Os limites abaixo mudam de tempos em tempos. Confirme na doc oficial
de especificacao de acessorios antes de rodar numa leva grande.
]]
local ServerStorage = game:GetService("ServerStorage")
type Caixa = { x: number, y: number, z: number }
-- Caixa maxima (em studs) por ponto de encaixe.
local BBOX: { [string]: Caixa } = {
HatAttachment = { x = 2.5, y = 2.5, z = 2.5 },
HairAttachment = { x = 2.5, y = 2.5, z = 2.5 },
FaceFrontAttachment = { x = 1.5, y = 1.5, z = 1.0 },
NeckAttachment = { x = 2.0, y = 1.5, z = 1.5 },
FrontAttachment = { x = 2.0, y = 2.0, z = 1.0 },
BackAttachment = { x = 2.5, y = 3.0, z = 1.5 },
WaistFrontAttachment = { x = 2.0, y = 1.0, z = 1.0 },
WaistBackAttachment = { x = 2.0, y = 1.0, z = 1.0 },
WaistCenterAttachment = { x = 2.0, y = 1.0, z = 1.0 },
LeftShoulderAttachment = { x = 1.0, y = 2.0, z = 1.0 },
RightShoulderAttachment = { x = 1.0, y = 2.0, z = 1.0 },
}
-- Termos que costumam derrubar nome/descricao. Adicione os seus.
local TERMOS_RISCO: { string } = {
"naruto", "goku", "sonic", "mario", "pikachu", "mickey", "batman",
"nike", "adidas", "gucci", "supreme", "louis vuitton",
"discord", "tiktok", "instagram", "youtube", "twitter",
"free", "gratis", "robux", "promo", "code", "giveaway",
"http", "www", "@", ".com", "dm me", "add me",
"gun", "blood", "sangue", "weed", "vape", "sexy", "nude",
}
local reprovas = 0
local atencoes = 0
local function reprova(alvo: Instance, msg: string)
reprovas += 1
warn(("[REPROVA] %s -> %s"):format(alvo.Name, msg))
end
local function atencao(alvo: Instance, msg: string)
atencoes += 1
print(("[ATENCAO] %s -> %s"):format(alvo.Name, msg))
end
-- deixa o texto comparavel: minusculo, sem separadores, sem numero-letra
local function normalizar(txt: string): string
local baixo = string.lower(txt)
baixo = (string.gsub(baixo, "[%-_%.%s]+", " "))
baixo = (string.gsub(baixo, "0", "o"))
baixo = (string.gsub(baixo, "1", "i"))
baixo = (string.gsub(baixo, "3", "e"))
baixo = (string.gsub(baixo, "4", "a"))
baixo = (string.gsub(baixo, "5", "s"))
return baixo
end
local function checarTexto(acc: Instance, rotulo: string, txt: string)
if txt == "" then
return
end
local alvo = normalizar(txt)
for _, termo in TERMOS_RISCO do
if string.find(alvo, termo, 1, true) then
reprova(acc, ("%s contem termo de risco: '%s'"):format(rotulo, termo))
end
end
end
local function checarAccessory(acc: Accessory)
-- 1. Handle
local handle = acc:FindFirstChild("Handle")
if not handle or not handle:IsA("BasePart") then
reprova(acc, "nao tem uma BasePart chamada 'Handle'")
return
end
-- 2. Attachment unico e com nome reconhecido
local attachments: { Attachment } = {}
for _, filho in handle:GetChildren() do
if filho:IsA("Attachment") then
table.insert(attachments, filho)
end
end
if #attachments == 0 then
reprova(acc, "Handle sem Attachment: o item nao encaixa em lugar nenhum")
elseif #attachments > 1 then
reprova(acc, ("Handle com %d Attachments; use exatamente 1"):format(#attachments))
else
local att = attachments[1]
local limite = BBOX[att.Name]
if not limite then
reprova(acc, ("nome de Attachment invalido: '%s'"):format(att.Name))
else
-- 3. Caixa
local s = handle.Size
if s.X > limite.x or s.Y > limite.y or s.Z > limite.z then
reprova(acc, ("tamanho %.2f x %.2f x %.2f passa do limite %.2f x %.2f x %.2f de %s")
:format(s.X, s.Y, s.Z, limite.x, limite.y, limite.z, att.Name))
end
end
end
-- 4. Transparencia
if handle.Transparency > 0 then
reprova(acc, ("Handle com Transparency %.2f: leitura automatica de conteudo escondido"):format(handle.Transparency))
end
-- 5. Lixo dentro do item
for _, filho in handle:GetDescendants() do
if filho:IsA("BaseScript") then
reprova(acc, ("tem script dentro do Handle: %s"):format(filho.Name))
elseif filho:IsA("Decal") or filho:IsA("Texture") then
reprova(acc, ("tem %s dentro do Handle; a textura vai no MeshPart"):format(filho.ClassName))
end
end
-- 6. Textura presente
if handle:IsA("MeshPart") then
local temSurface = handle:FindFirstChildWhichIsA("SurfaceAppearance") ~= nil
if handle.TextureID == "" and not temSurface then
atencao(acc, "MeshPart sem TextureID e sem SurfaceAppearance")
end
else
atencao(acc, ("Handle e '%s', nao MeshPart"):format(handle.ClassName))
end
-- 7. Nome e descricao
checkarNomeEDescricao(acc)
end
function checkarNomeEDescricao(acc: Accessory)
checkarTextoInterno(acc)
end
function checkarTextoInterno(acc: Accessory)
checkarTexto(acc)
end
function checkarTexto(acc: Accessory)
checkarTexto_impl(acc)
end
function checkarTexto_impl(acc: Accessory)
checkarTexto2(acc)
end
function checkarTexto2(acc: Accessory)
local desc = acc:GetAttribute("Descricao")
checkarTexto3(acc, desc)
end
function checkarTexto3(acc: Accessory, desc: any)
checkarTexto(acc, "nome", acc.Name)
if typeof(desc) == "string" then
checkarTexto(acc, "descricao", desc)
else
atencao(acc, "sem atributo 'Descricao': a descricao nao foi checada")
end
end
local pasta = ServerStorage:FindFirstChild("UGC_Check")
if not pasta then
warn("[UGC] crie uma pasta chamada 'UGC_Check' em ServerStorage e ponha os Accessory dentro")
return
end
local total = 0
for _, filho in pasta:GetChildren() do
if filho:IsA("Accessory") then
total += 1
checkarAccessory(filho)
else
atencao(filho, ("nao e Accessory (e '%s'); ignorado"):format(filho.ClassName))
end
end
print(("[UGC] %d itens checados | %d reprovas | %d atencoes"):format(total, reprovas, atencoes))
print("[UGC] o script nao conta triangulos nem le a imagem da textura. Isso e olho humano no Blender.")