[{"data":1,"prerenderedAt":992},["ShallowReactive",2],{"blog-pt-supabase-bucket-not-found":3,"blog-index-pt":461},{"id":4,"title":5,"body":6,"category":418,"cover":419,"coverAlt":420,"description":421,"draft":422,"extension":423,"faq":424,"image":440,"keywords":441,"meta":449,"navigation":450,"ogTitle":5,"path":451,"published":452,"seo":453,"stem":454,"tldr":455,"updated":452,"__hash__":460},"blog_pt\u002Fblog\u002Fsupabase-bucket-not-found.md","Supabase \"Bucket not found\": as três coisas que isso significa",{"type":7,"value":8,"toc":405},"minimark",[9,13,16,27,30,38,43,46,49,75,78,100,104,107,113,119,122,133,136,142,146,164,167,170,176,180,183,192,195,210,215,219,222,225,228,239,243,246,256,270,273,277,280,292,299,303,306,315,333,342,359,363,392],[10,11,12],"p",{},"Seu app mostra uma imagem quebrada onde deveria haver uma foto. Ou um upload\nfalha, e a mensagem que volta tem três palavras: \"Bucket not found\". Aí você\nabre o Supabase, vai em Storage, e o bucket está ali mesmo, na lista.",[10,14,15],{},"Abra o endereço da imagem numa aba separada e o Storage responde isto:",[17,18,23],"pre",{"className":19,"code":21,"language":22},[20],"language-text","{\n  \"statusCode\": \"404\",\n  \"code\": \"NoSuchBucket\",\n  \"error\": \"Bucket not found\",\n  \"message\": \"Bucket not found\"\n}\n","text",[24,25,21],"code",{"__ignoreMap":26},"",[10,28,29],{},"Esse é o corpo que o código-fonte do Supabase Storage monta hoje, lido em 17 de\noutubro de 2026. Supabase \"Bucket not found\" cobre três situações diferentes com\nesse mesmo corpo, e na primeira delas o bucket está exatamente onde você o\ndeixou.",[10,31,32,33,37],{},"E é aqui que guia após guia erra: ",[34,35,36],"strong",{},"a primeira solução que você vai encontrar é\ndeixar o bucket público, e quando ela funciona, funciona porque cada arquivo\ndesse bucket também passa a ser público."," Para duas das três causas, ela não\nmuda absolutamente nada. Para a que sobra, ela troca uma imagem quebrada por um\nbucket que qualquer pessoa com o endereço de um arquivo consegue ler.",[39,40,42],"h2",{"id":41},"o-que-significa-supabase-bucket-not-found","O que significa Supabase \"Bucket not found\"?",[10,44,45],{},"O Storage procurou um bucket com exatamente o nome da sua requisição, dentro do\nprojeto que sua requisição alcançou, e não encontrou nenhum que estivesse\ndisposto a servir para essa requisição.",[10,47,48],{},"Essa última parte está ali porque um bucket tem mais de uma porta, e cada porta\nfaz a pergunta do seu jeito. O código-fonte do Storage mostra três delas:",[50,51,52,63,69],"ul",{},[53,54,55,58,59,62],"li",{},[34,56,57],{},"Um endereço público de arquivo",", o que o ",[24,60,61],{},"getPublicUrl"," gera. Essa porta\nsó conta os buckets marcados como públicos, então um bucket privado aparece\naqui como \"não encontrado\" mesmo existindo.",[53,64,65,68],{},[34,66,67],{},"Um upload."," Essa porta conta todos os buckets do projeto, os privados\ninclusive. \"Não encontrado\" aqui significa que esse nome de fato não existe\nnesse projeto.",[53,70,71,74],{},[34,72,73],{},"Um pedido da lista de arquivos de um bucket."," Essa porta nunca diz \"Bucket\nnot found\". Um bucket que não existe responde com uma lista vazia, a mesma\nresposta que um bucket vazio dá, e isso a gente vê de fora toda vez que nosso\nscanner pergunta.",[10,76,77],{},"Então a primeira tarefa é descobrir por qual porta a requisição que falhou\nentrou.",[10,79,80,83,84,87,88,91,92,95,96,99],{},[34,81,82],{},"Os dois números dessa mensagem não batem, e isso confunde o tratamento de\nerros."," O corpo diz ",[24,85,86],{},"\"statusCode\": \"404\"",", enquanto a requisição em si falha\ncom o status HTTP 400. O Storage envia esse erro com um 400 e guarda o próprio\n404 dentro do corpo. A biblioteca supabase-js repassa os dois para o seu código:\n",[24,89,90],{},"error.status"," é 400 e ",[24,93,94],{},"error.statusCode"," é ",[24,97,98],{},"\"404\"",". O código que seu builder\nescreveu para pegar um 404 vai deixar esse passar.",[39,101,103],{"id":102},"causa-1-um-link-público-para-um-bucket-privado","Causa 1: um link público para um bucket privado",[10,105,106],{},"Essa é a causa das imagens quebradas. O endereço foi montado para um bucket\npúblico, e o bucket é privado.",[10,108,109,110,112],{},"O ",[24,111,61],{}," não pergunta nada ao Supabase. Ele junta o endereço do seu\nprojeto, o nome do bucket e o nome do arquivo num link, dentro do seu app, e\ndevolve esse link. A nota acima dessa função, na própria biblioteca cliente do\nSupabase, diz isso em duas frases:",[114,115,116],"blockquote",{},[10,117,118],{},"Esta função não verifica se o bucket é público. Se uma URL pública for criada\npara um bucket que não é público, você não vai conseguir baixar o arquivo.",[10,120,121],{},"Mais tarde, o navegador de um visitante pede esse link, e o Storage procura o\nbucket só entre os buckets públicos. Um bucket privado não passa nessa busca,\nigualzinho a um que não existe, e a resposta é \"Bucket not found\".",[10,123,124,125,128,129,132],{},"Dá para reconhecer essa causa pelo próprio link. Um endereço público de arquivo\ncontém ",[24,126,127],{},"\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002F"," seguido do nome do bucket. Se esse bucket\nnão tem nenhuma marca de público em ",[34,130,131],{},"Storage → Buckets",", o link nunca ia\nabrir, seja qual for a grafia do nome.",[10,134,135],{},"Buckets novos começam privados, então a configuração está se comportando como\ndeveria. O que aconteceu é que o código, seu ou do seu builder, foi escrito para\num bucket público e apontado para um privado.",[137,138],"diagram",{"alt":139,"caption":140,"src":141},"Um depósito de imagens com um selo de cadeado e duas aberturas na parede esquerda. Um cartão com getPublicUrl manda uma seta âmbar para a abertura de cima, fechada por uma barra e com um X acima. Um cartão com createSignedUrl manda uma seta turquesa para a abertura de baixo, com a barra levantada, e uma imagem sai pelo outro lado do depósito em direção a uma pessoa ao lado de um visto.","Um único bucket privado, duas formas de pedir um arquivo. O endereço público é barrado na porta, e o link assinado passa até o mesmo arquivo.","\u002Fblog\u002Fsupabase-bucket-not-found\u002Ftwo-doors-1600x720.png",[39,143,145],{"id":144},"causa-2-um-nome-que-não-é-bem-o-nome-do-bucket","Causa 2: um nome que não é bem o nome do bucket",[10,147,148,149,152,153,156,157,160,161,163],{},"O Storage compara o nome do bucket caractere por caractere, então ",[24,150,151],{},"Avatars"," e\n",[24,154,155],{},"avatars"," são dois buckets diferentes, assim como ",[24,158,159],{},"avatar"," e ",[24,162,155],{},".",[10,165,166],{},"No código-fonte do Storage, a busca é uma igualdade simples sobre o id do\nbucket. Maiúsculas contam, uma letra faltando conta, e um hífen onde o bucket\ntem um sublinhado conta. Cada um desses casos volta como as mesmas três\npalavras.",[10,168,169],{},"Um app feito com uma ferramenta de IA pode chegar aqui sem ninguém ter digitado\nnada errado. O código que envia ou mostra um arquivo é escrito numa etapa, e o\nbucket que ele cita deveria ser criado em outra. Se essa segunda etapa nunca\nrodou, ou rodou com um nome um pouco diferente, o código está pedindo um bucket\nque ninguém criou.",[10,171,172,173,175],{},"A conferência pede duas listas. Abra ",[34,174,131],{}," e anote o nome de\ncada bucket exatamente como aparece. Depois diga ao seu builder, com palavras\nsimples: liste cada nome de bucket do Storage que este app usa, e me mostre onde\ncada um é usado. Qualquer nome da lista dele que falte na sua é o que está\nfalhando.",[39,177,179],{"id":178},"causa-3-o-bucket-está-em-outro-projeto","Causa 3: o bucket está em outro projeto",[10,181,182],{},"Seu app conversa com um único projeto do Supabase, o do endereço do Supabase\ndele, e um bucket criado em qualquer outro projeto simplesmente não existe para\no seu app.",[10,184,185,186,191],{},"É num upload que essa causa aparece com mais clareza. Num upload, o Storage\nprocura o bucket no projeto inteiro sem aplicar suas regras de acesso, então\n\"Bucket not found\" num upload nunca é um problema de permissão. Quando o bucket\nexiste e suas regras recusam o arquivo, o Storage responde com\n",[187,188,190],"a",{"href":189},"\u002Fblog\u002Fstorage-upload-violates-row-level-security","outra mensagem, que fala de row-level security",".\nEntão \"Bucket not found\" num upload significa que esse nome não existe no\nprojeto em que seu app está gravando.",[10,193,194],{},"Existem jeitos bem comuns de acabar com dois projetos: um projeto de teste ao\nlado do de produção, uma cópia do app ligada a um projeto novo, um projeto\ncriado na mão para testar alguma coisa. O bucket é criado naquele que estava\naberto no painel naquele momento.",[10,196,197,198,201,202,205,206,209],{},"A conferência é uma comparação entre duas sequências curtas. O endereço do\nSupabase do seu app tem a forma ",[24,199,200],{},"https:\u002F\u002F\u003Cref>.supabase.co",", e a parte antes de\n",[24,203,204],{},".supabase.co"," é a referência do projeto. O endereço do seu painel traz a mesma\nreferência depois de ",[24,207,208],{},"\u002Fproject\u002F",". Se as duas forem diferentes, você está olhando\npara um projeto enquanto seu app conversa com outro.",[137,211],{"alt":212,"caption":213,"src":214},"À esquerda, uma janela de app com uma seta turquesa para o projeto cuja referência bate com a dele. Esse projeto tem dois buckets apagados e um contorno tracejado onde deveria haver um terceiro, marcado com um X âmbar. À direita, um projeto separado com outra referência guarda o próprio bucket, aceso em turquesa, sem nada ligando ele ao app.","O bucket existe. Ele foi criado no projeto da direita, e cada requisição do seu app vai para o da esquerda.","\u002Fblog\u002Fsupabase-bucket-not-found\u002Ftwo-projects-1600x700.png",[39,216,218],{"id":217},"você-deve-deixar-o-bucket-público-para-resolver","Você deve deixar o bucket público para resolver?",[10,220,221],{},"Só quando cada arquivo do bucket for feito para qualquer pessoa que tenha o\nendereço, e só para a primeira causa. Com um nome errado ou um projeto errado, o\nbotão não muda nada.",[10,223,224],{},"Um bucket público faz uma coisa só, e a documentação do Supabase a descreve em\numa linha: qualquer pessoa que tenha o endereço de um arquivo consegue abri-lo.\nNenhum login entra nisso. Os próprios exemplos do Supabase são fotos de perfil,\nmídia pública e conteúdo de posts de blog, e logos ou fotos de produtos entram\nno mesmo grupo.",[10,226,227],{},"É a configuração errada para notas fiscais, documentos de identidade\nescaneados, exportações ou qualquer coisa que pertença a uma só pessoa. O botão\nvale para o bucket inteiro e para cada arquivo que chegar nele depois, inclusive\narquivos de uma funcionalidade que você ainda nem construiu.",[10,229,230,231,234,235,238],{},"O mesmo atalho tem um gêmeo do lado das regras, e é esse que a gente mede. Uma\nregra em ",[24,232,233],{},"storage.objects"," que só cita o bucket faz os downloads funcionarem\npara todo mundo, e também entrega a lista de nomes do bucket. Escaneamos 8.435\napps no ar que citam um projeto do Supabase. A verificação de buckets teve\nresposta em 4.703 deles, e ",[34,236,237],{},"792 responderam ao nosso pedido de lista com os\nnomes do que havia dentro",", sem ninguém logado. Isso é mais ou menos um em\ncada seis dos apps que conseguimos consultar. Quando um bucket é público e a\nlista dele também está aberta, cada nome dessa lista é um link que funciona.",[39,240,242],{"id":241},"como-mostrar-um-arquivo-privado-sem-deixá-lo-público","Como mostrar um arquivo privado sem deixá-lo público",[10,244,245],{},"Dê à página um link assinado: um endereço que funciona pelo número de segundos\nque você escolher e depois para de funcionar.",[10,247,248,249,252,253,255],{},"A documentação do Supabase cita duas formas de tirar um arquivo de um bucket\nprivado. Uma é um download que leva a sessão da pessoa logada. A outra é o\n",[24,250,251],{},"createSignedUrl",", que gera um link \"que pode ser acessado por um tempo\nlimitado\". É essa segunda que entra no lugar do ",[24,254,61],{}," em qualquer\npágina que mostre uma imagem.",[10,257,258,259,262,263,265,266,269],{},"Um link assinado continua obedecendo às suas regras. Antes de o Storage\nassinar qualquer coisa, o código-fonte dele confere se a pessoa que está pedindo\npode ler aquele arquivo, então um bucket privado precisa de uma regra ",[24,260,261],{},"select","\nem ",[24,264,233],{}," que diga quem pode ler o quê.\n",[187,267,268],{"href":189},"O erro de upload explica como essas regras são escritas",",\ninclusive por que uma regra de leitura que só cita o bucket também abre a lista\ndele.",[10,271,272],{},"Para passar isso ao seu builder, com palavras simples: para o bucket que dá o\nerro \"Bucket not found\", troque getPublicUrl por createSignedUrl, mantenha o\nbucket privado e adicione uma policy de Storage que deixe cada pessoa ler só os\narquivos que ela deve ver. Depois recarregue a página que estava com a imagem\nquebrada.",[39,274,276],{"id":275},"o-que-seus-buckets-estão-mostrando-a-estranhos-agora","O que seus buckets estão mostrando a estranhos agora",[10,278,279],{},"Duas telas do painel dizem o que você configurou, e uma verificação de fora diz\no que um estranho recebe.",[10,281,282,284,285,288,289,291],{},[34,283,131],{}," mostra quais buckets são públicos. Para cada um, pergunte\nse cada arquivo ali é algo que você mostraria a um estranho. ",[34,286,287],{},"Storage →\nPolicies"," mostra as regras. Uma regra ",[24,290,261],{}," cuja única condição é o nome do\nbucket deixa qualquer pessoa ler esse bucket, lista de arquivos incluída.",[10,293,294,295,163],{},"Nosso scan gratuito pede ao seu projeto no ar a lista de arquivos de cada bucket\nusando só a chave que já está no código do seu app, do jeito que um estranho\nfaria, e diz quais buckets responderam com nomes. Ele lê nomes e nunca baixa um\narquivo. Leva uns 20 segundos e não precisa de conta:\n",[187,296,298],{"href":297},"\u002Fsecurity-scanner","escaneie seu app",[39,300,302],{"id":301},"mantendo-seus-arquivos-onde-você-os-colocou","Mantendo seus arquivos onde você os colocou",[10,304,305],{},"Depois da correção de hoje, duas coisas ainda podem mudar: alguém mexe numa\nconfiguração enquanto corre atrás de outro bug, e um arquivo de que alguém\nprecisava é apagado.",[10,307,308],{},[34,309,310,314],{},[187,311,313],{"href":312},"\u002Fwebsite-monitoring","Reeve Monitor"," continua verificando de fora:",[50,316,317,320,323,330],{},[53,318,319],{},"a verificação de segurança completa, repetida num cronograma, incluindo a da listagem de buckets",[53,321,322],{},"se seu app está no ar",[53,324,325,326,329],{},"uma mensagem quando um resultado ",[34,327,328],{},"muda",", para que um bucket que abriu durante a noite não fique esperando você olhar",[53,331,332],{},"um relatório mensal, em linguagem simples, do que ele viu",[10,334,335],{},[34,336,337,341],{},[187,338,340],{"href":339},"\u002Fsupabase-backups","Reeve Care"," guarda uma cópia do que tem lá dentro:",[50,343,344,347,350,353,356],{},[53,345,346],{},"uma cópia criptografada do seu banco de dados do Supabase num cronograma, no armazenamento próprio da Reeve na UE, fora da sua conta do Supabase",[53,348,349],{},"cada cópia verificada antes de valer, contando as linhas de cada tabela",[53,351,352],{},"também seus arquivos enviados, assim que você conecta uma credencial do Storage",[53,354,355],{},"uma restauração com um clique, com uma cópia de segurança do estado atual feita antes",[53,357,358],{},"tudo o que o Monitor faz",[39,360,362],{"id":361},"o-que-fazer-hoje","O que fazer hoje",[364,365,366],"key-takeaways",{},[50,367,368,374,377,380,383],{},[53,369,370,371,373],{},"Abra o link que falha numa aba separada. Se o endereço contém ",[24,372,127],{}," e o bucket é privado, é a primeira causa.",[53,375,376],{},"Copie o nome do bucket em Storage → Buckets e compare, maiúsculas incluídas, com o nome que seu app usa.",[53,378,379],{},"Compare a referência do projeto no endereço do Supabase do seu app com a do endereço do seu painel.",[53,381,382],{},"Mantenha um bucket privado a menos que cada arquivo dele seja feito para qualquer pessoa que tenha o endereço, e sirva arquivos privados por links assinados.",[53,384,385,386,388,389,391],{},"Leia cada regra ",[24,387,261],{}," em ",[24,390,233],{},". Uma que só cita o bucket entrega também a lista de arquivos.",[10,393,394,395,399,400,404],{},"Comece pela requisição que falhou, porque a porta por onde ela entrou diz qual\ndas três causas conferir. O ",[187,396,398],{"href":397},"\u002Fchecklist","checklist de segurança de 10 minutos","\ncobre o que um app recém-lançado costuma deixar aberto além disso, e\n",[187,401,403],{"href":402},"\u002Fblog\u002Fsupabase-storage-bucket-public","o que um bucket público expõe"," é a\npróxima leitura se algum dos seus se revelou público.",{"title":26,"searchDepth":406,"depth":406,"links":407},3,[408,410,411,412,413,414,415,416,417],{"id":41,"depth":409,"text":42},2,{"id":102,"depth":409,"text":103},{"id":144,"depth":409,"text":145},{"id":178,"depth":409,"text":179},{"id":217,"depth":409,"text":218},{"id":241,"depth":409,"text":242},{"id":275,"depth":409,"text":276},{"id":301,"depth":409,"text":302},{"id":361,"depth":409,"text":362},"Noções de segurança","\u002Fblog\u002Fsupabase-bucket-not-found\u002Fcover-1200x630.png","Uma prateleira de buckets, um deles fechado com cadeado. Na frente, uma etiqueta âmbar cuja linha tracejada para numa barra antes dele.","Supabase \"Bucket not found\" é uma de três coisas: um link público para um bucket privado, um nome que não bate exatamente ou o projeto errado.",false,"md",[425,428,431,434,437],{"q":426,"a":427},"Por que o Supabase diz que meu bucket não existe se eu estou vendo ele?","Porque o Storage procura um bucket de jeitos diferentes conforme a requisição. Um endereço público de arquivo, o que o getPublicUrl gera, só é procurado entre os buckets públicos, então um bucket privado que você vê no painel aparece ali como não encontrado. Se o erro veio de um upload, o nome no seu código não bate exatamente com nenhum bucket do projeto ao qual seu app está conectado.",{"q":429,"a":430},"O nome de um bucket do Supabase diferencia maiúsculas e minúsculas?","Sim. O Storage compara o nome caractere por caractere, então Avatars e avatars são dois buckets diferentes, assim como avatar e avatars. Copie o nome em Storage → Buckets no seu painel e compare com o nome que seu app usa.",{"q":432,"a":433},"Devo deixar meu bucket público para resolver \"Bucket not found\"?","Só se cada arquivo dele for feito para qualquer pessoa que tenha o endereço, como fotos de perfil ou fotos de produtos. Público significa que qualquer pessoa com o endereço de um arquivo pode abri-lo sem entrar na conta. Isso só resolve o erro quando um link público foi criado para um bucket privado; um nome errado ou um projeto errado continua quebrado de qualquer jeito. Para arquivos que pertencem a uma só pessoa, mantenha o bucket privado e use um link assinado.",{"q":435,"a":436},"Como mostro um arquivo de um bucket privado?","Com um link assinado. O createSignedUrl gera um endereço que funciona pelo número de segundos que você escolher e depois para de funcionar, e ele entra no lugar do getPublicUrl em qualquer página que mostre o arquivo. Quem pede o link precisa ter permissão para ler o arquivo, então o bucket precisa de uma regra select em storage.objects que diga quem pode ler o quê.",{"q":438,"a":439},"Por que o erro diz 404 se a requisição falhou com 400?","O Supabase Storage envia esse erro com o status HTTP 400 e coloca o próprio status, 404, dentro do corpo como statusCode. No supabase-js isso chega como error.status 400 e error.statusCode \"404\", e é por isso que um código escrito para pegar um 404 deixa esse erro passar sem perceber.","\u002Fblog\u002Fsupabase-bucket-not-found\u002Fcard-800x500.png",[442,443,444,445,446,447,448],"supabase bucket not found","supabase storage bucket not found","bucket not found getpublicurl","supabase url pública bucket not found","supabase upload bucket not found","supabase storage 404","supabase url assinada bucket privado",{},true,"\u002Fblog\u002Fsupabase-bucket-not-found","2026-10-17",{"title":5,"description":421},"blog\u002Fsupabase-bucket-not-found",[456,457,458,459],"Supabase \"Bucket not found\" significa que o Storage procurou um bucket com exatamente esse nome, no projeto que sua requisição alcançou, e não encontrou nenhum que estivesse disposto a servir para essa requisição. O bucket pode continuar lá, no seu painel.","Um link criado pelo getPublicUrl para um bucket privado dá esse erro quando é aberto, porque o Storage só serve esses links a partir de buckets públicos.","Num upload, significa que o nome não existe nesse projeto. Confira a grafia e as maiúsculas, e depois para qual projeto seu app aponta.","Deixar o bucket público acaba com a mensagem e permite que qualquer pessoa com o endereço de um arquivo o abra. Para arquivos que pertencem a uma só pessoa, use um link assinado.","kgizIQgFLJnDsbqPliJymgQJsJ-SRK3v8YS4iRrvpg8",[462,468,474,480,486,492,498,504,510,516,522,529,535,541,547,553,559,565,571,577,583,589,595,601,602,608,614,620,626,632,637,643,649,655,661,667,673,679,685,691,697,703,709,715,721,727,732,738,744,750,756,762,768,774,780,786,792,798,804,810,816,822,828,834,840,846,852,858,864,870,876,882,888,894,900,906,912,918,924,930,935,941,947,953,958,964,970,976,981,987],{"path":463,"title":464,"description":465,"published":466,"category":418,"image":467,"draft":422},"\u002Fblog\u002Fmax-client-connections-reached","Supabase \"max client connections reached\", explicado","Supabase \"max client connections reached\": o pooler não tem lugar para mais um cliente. A porta da sua string de conexão define o limite.","2026-11-09","\u002Fblog\u002Fmax-client-connections-reached\u002Fcard-800x500.png",{"path":469,"title":470,"description":471,"published":472,"category":418,"image":473,"draft":422},"\u002Fblog\u002Funsupported-provider-provider-is-not-enabled","Erro do Supabase: \"Unsupported provider: provider is not enabled\"","\"Unsupported provider: provider is not enabled\": o Google está desativado no seu projeto Supabase. Como ativar e corrigir o redirect_uri_mismatch.","2026-11-08","\u002Fblog\u002Funsupported-provider-provider-is-not-enabled\u002Fcard-800x500.png",{"path":475,"title":476,"description":477,"published":478,"category":418,"image":479,"draft":422},"\u002Fblog\u002Fviolates-foreign-key-constraint","Erro do Supabase \"violates foreign key constraint\" ao inserir","Supabase \"insert or update on table violates foreign key constraint\": sua linha aponta para uma linha que não existe. Qual, por quê, e como corrigir.","2026-11-07","\u002Fblog\u002Fviolates-foreign-key-constraint\u002Fcard-800x500.png",{"path":481,"title":482,"description":483,"published":484,"category":418,"image":485,"draft":422},"\u002Fblog\u002Fnull-value-violates-not-null-constraint","Erro do Supabase \"null value in column violates not-null constraint\"","Supabase \"null value in column violates not-null constraint\": uma coluna obrigatória chegou vazia. De onde veio o null, e como corrigir.","2026-11-06","\u002Fblog\u002Fnull-value-violates-not-null-constraint\u002Fcard-800x500.png",{"path":487,"title":488,"description":489,"published":490,"category":418,"image":491,"draft":422},"\u002Fblog\u002Fauth-session-missing","Supabase \"Auth session missing!\": para onde foi a sessão","\"Auth session missing!\" é o supabase-js sem achar nenhuma sessão logada e sem chegar a perguntar ao Supabase. Para onde foi a sessão, e a correção.","2026-11-05","\u002Fblog\u002Fauth-session-missing\u002Fcard-800x500.png",{"path":493,"title":494,"description":495,"published":496,"category":418,"image":497,"draft":422},"\u002Fblog\u002Finvalid-claim-missing-sub-claim","Supabase \"invalid claim: missing sub claim\": ninguém está logado","\"invalid claim: missing sub claim\": o Supabase Auth recebeu um token autêntico sem nenhum usuário, a chave do projeto no lugar de uma sessão.","2026-11-04","\u002Fblog\u002Finvalid-claim-missing-sub-claim\u002Fcard-800x500.png",{"path":499,"title":500,"description":501,"published":502,"category":418,"image":503,"draft":422},"\u002Fblog\u002Ffailed-to-send-a-request-to-the-edge-function","\"Failed to send a request to the Edge Function\": a causa real","\"Failed to send a request to the Edge Function\": o navegador não recebeu uma resposta legível. O console dele diz por quê e se a sua função rodou.","2026-11-03","\u002Fblog\u002Ffailed-to-send-a-request-to-the-edge-function\u002Fcard-800x500.png",{"path":505,"title":506,"description":507,"published":508,"category":418,"image":509,"draft":422},"\u002Fblog\u002Fsupabase-auth-redirects-to-localhost","Por que o Supabase redireciona links de e-mail para localhost:3000","Se o Supabase redireciona para localhost:3000, a Site URL nunca foi trocada ou o seu endereço falta em Redirect URLs. A solução, e o curinga a evitar.","2026-11-02","\u002Fblog\u002Fsupabase-auth-redirects-to-localhost\u002Fcard-800x500.png",{"path":511,"title":512,"description":513,"published":514,"category":418,"image":515,"draft":422},"\u002Fblog\u002Femail-link-is-invalid-or-has-expired","Supabase \"Email link is invalid or has expired\" num link novo","Num link enviado há um minuto, \"Email link is invalid or has expired\" no Supabase costuma significar que um filtro de e-mail o usou antes. Como resolver.","2026-11-01","\u002Fblog\u002Femail-link-is-invalid-or-has-expired\u002Fcard-800x500.png",{"path":517,"title":518,"description":519,"published":520,"category":418,"image":521,"draft":422},"\u002Fblog\u002Fcanceling-statement-due-to-statement-timeout","Supabase \"canceling statement due to statement timeout\", explicado","Supabase \"canceling statement due to statement timeout\": uma consulta passou do limite do seu papel, 3 segundos para um visitante. Veja antes a política RLS.","2026-10-31","\u002Fblog\u002Fcanceling-statement-due-to-statement-timeout\u002Fcard-800x500.png",{"path":523,"title":524,"description":525,"published":526,"category":527,"image":528,"draft":422},"\u002Fblog\u002Fdatabase-error-deleting-user","\"Database error deleting user\" no Supabase, e o que vai junto","\"Database error deleting user\" no Supabase: seu banco recusou a exclusão. O motivo está nos seus logs, e a correção decide o que mais é apagado.","2026-10-30","Backups","\u002Fblog\u002Fdatabase-error-deleting-user\u002Fcard-800x500.png",{"path":530,"title":531,"description":532,"published":533,"category":418,"image":534,"draft":422},"\u002Fblog\u002Fstripe-webhook-no-signatures-found","\"No signatures found matching the expected signature\" no Supabase","O webhook do Stripe numa Edge Function do Supabase diz \"No signatures found matching the expected signature\"? São duas causas. Continue verificando.","2026-10-29","\u002Fblog\u002Fstripe-webhook-no-signatures-found\u002Fcard-800x500.png",{"path":536,"title":537,"description":538,"published":539,"category":418,"image":540,"draft":422},"\u002Fblog\u002Fsupabase-invalid-login","\"Invalid login credentials\" no Supabase: as três causas","O Supabase diz \"Invalid login credentials\" para senha errada, e-mail desconhecido e conta Google. Como saber qual é, e por que é vago.","2026-10-28","\u002Fblog\u002Fsupabase-invalid-login\u002Fcard-800x500.png",{"path":542,"title":543,"description":544,"published":545,"category":418,"image":546,"draft":422},"\u002Fblog\u002Fedge-function-returned-a-non-2xx-status-code","\"Edge Function returned a non-2xx status code\": o erro real","\"Edge Function returned a non-2xx status code\" quer dizer que sua função do Supabase respondeu com um erro. Veja onde ler o erro real.","2026-10-27","\u002Fblog\u002Fedge-function-returned-a-non-2xx-status-code\u002Fcard-800x500.png",{"path":548,"title":549,"description":550,"published":551,"category":418,"image":552,"draft":422},"\u002Fblog\u002Fcertificate-not-trusted","Certificado não confiável: três causas além do vencimento","Certificado não confiável mesmo com a data certa? Ele cita outro endereço, assinou a si mesmo ou falta um elo na cadeia. Veja como saber qual.","2026-10-26","\u002Fblog\u002Fcertificate-not-trusted\u002Fcard-800x500.png",{"path":554,"title":555,"description":556,"published":557,"category":418,"image":558,"draft":422},"\u002Fblog\u002Finvalid-input-syntax-for-type-uuid","Supabase \"invalid input syntax for type uuid\": leia as aspas","Supabase \"invalid input syntax for type uuid\": seu app enviou algo que não é um id. Leia as aspas, segure a consulta, mantenha a coluna.","2026-10-25","\u002Fblog\u002Finvalid-input-syntax-for-type-uuid\u002Fcard-800x500.png",{"path":560,"title":561,"description":562,"published":563,"category":418,"image":564,"draft":422},"\u002Fblog\u002Fduplicate-key-value-violates-unique-constraint","Supabase \"duplicate key value violates unique constraint\", explicado","Supabase \"duplicate key value violates unique constraint\": o valor já está em uso. Ache a coluna, escolha uma correção e tire o valor da tela.","2026-10-24","\u002Fblog\u002Fduplicate-key-value-violates-unique-constraint\u002Fcard-800x500.png",{"path":566,"title":567,"description":568,"published":569,"category":418,"image":570,"draft":422},"\u002Fblog\u002Fsupabase-relation-does-not-exist","Supabase \"relation does not exist\" e a tabela está lá","Supabase \"relation does not exist\" ou PGRST205: nenhuma tabela tem esse nome nesse schema. Quatro verificações, e o que expor um schema abre.","2026-10-23","\u002Fblog\u002Fsupabase-relation-does-not-exist\u002Fcard-800x500.png",{"path":572,"title":573,"description":574,"published":575,"category":418,"image":576,"draft":422},"\u002Fblog\u002Fsupabase-function-not-found","Supabase PGRST202: \"Could not find the function in the schema cache\"","Supabase \"Could not find the function in the schema cache\" mostra os nomes de argumentos que seu app enviou. Compare-os com a função.","2026-10-22","\u002Fblog\u002Fsupabase-function-not-found\u002Fcard-800x500.png",{"path":578,"title":579,"description":580,"published":581,"category":418,"image":582,"draft":422},"\u002Fblog\u002Fsupabase-schema-cache-column-error","Supabase PGRST204: \"Could not find the column in the schema cache\"","Supabase \"Could not find the column in the schema cache\" costuma ser um nome que não bate. Quatro verificações e a linha que recarrega.","2026-10-21","\u002Fblog\u002Fsupabase-schema-cache-column-error\u002Fcard-800x500.png",{"path":584,"title":585,"description":586,"published":587,"category":418,"image":588,"draft":422},"\u002Fblog\u002Fsupabase-email-rate-limit-exceeded","Supabase \"Email Rate Limit Exceeded\": dois limites, um só código","Supabase \"Email Rate Limit Exceeded\" limita cada email que seu projeto envia: 2 por hora no remetente embutido. O que conta e como aumentar.","2026-10-20","\u002Fblog\u002Fsupabase-email-rate-limit-exceeded\u002Fcard-800x500.png",{"path":590,"title":591,"description":592,"published":593,"category":418,"image":594,"draft":422},"\u002Fblog\u002Fsupabase-users-logged-out","Supabase \"Invalid Refresh Token: Refresh Token Not Found\": 3 causas","Supabase \"Invalid Refresh Token: Refresh Token Not Found\" desconecta seus usuários. Três causas, e como o log do Auth separa cada uma.","2026-10-19","\u002Fblog\u002Fsupabase-users-logged-out\u002Fcard-800x500.png",{"path":596,"title":597,"description":598,"published":599,"category":418,"image":600,"draft":422},"\u002Fblog\u002Fpermission-denied-for-schema-public","Supabase \"permission denied for schema public\": três causas","Supabase \"permission denied for schema public\" é um grant que falta no schema. O que o removeu, e a linha que o devolve.","2026-10-18","\u002Fblog\u002Fpermission-denied-for-schema-public\u002Fcard-800x500.png",{"path":451,"title":5,"description":421,"published":452,"category":418,"image":440,"draft":422},{"path":603,"title":604,"description":605,"published":606,"category":418,"image":607,"draft":422},"\u002Fblog\u002Fsupabase-invalid-jwt","Supabase invalid JWT: qual chave parou de funcionar?","Um erro Supabase invalid JWT é o PGRST301: um token assinado não passou na verificação. Num projeto novo isso é a sessão, não a chave de API.","2026-10-16","\u002Fblog\u002Fsupabase-invalid-jwt\u002Fcard-800x500.png",{"path":609,"title":610,"description":611,"published":612,"category":418,"image":613,"draft":422},"\u002Fblog\u002Fsupabase-single-row-error","Supabase \"multiple (or no) rows returned\" quase sempre é nenhuma","O Supabase devolve PGRST116, \"JSON object requested, multiple (or no) rows returned\", quando a consulta não achou nada. Linha escondida parece ausente.","2026-10-15","\u002Fblog\u002Fsupabase-single-row-error\u002Fcard-800x500.png",{"path":615,"title":616,"description":617,"published":618,"category":418,"image":619,"draft":422},"\u002Fblog\u002Fdatabase-error-saving-new-user","\"Database error saving new user\" no Supabase: onde olhar","\"Database error saving new user\" quer dizer que algo preso ao seu cadastro no Supabase falhou e tudo foi desfeito. O erro real está nos seus logs.","2026-10-14","\u002Fblog\u002Fdatabase-error-saving-new-user\u002Fcard-800x500.png",{"path":621,"title":622,"description":623,"published":624,"category":418,"image":625,"draft":422},"\u002Fblog\u002Fwhat-is-supabase","O que é Supabase? O banco de dados que seu builder escolheu","O que é Supabase: o banco de dados, o login e o armazenamento de arquivos do seu app. O Supabase cuida dos servidores; as regras das suas linhas são suas.","2026-10-13","\u002Fblog\u002Fwhat-is-supabase\u002Fcard-800x500.png",{"path":627,"title":628,"description":629,"published":630,"category":418,"image":631,"draft":422},"\u002Fblog\u002Faws-access-key-exposed-in-frontend","Uma chave AWS exposta no seu frontend não é como uma chave OpenAI","Uma chave de acesso da AWS exposta no seu frontend lê e grava no seu armazenamento. A solução costuma ser uma presigned URL, não uma chave nova.","2026-10-12","\u002Fblog\u002Faws-access-key-exposed-in-frontend\u002Fcard-800x500.png",{"path":189,"title":633,"description":634,"published":635,"category":418,"image":636,"draft":422},"\"Row-level security policy for table objects\" ao enviar","\"New row violates row-level security policy for table objects\" quer dizer que o seu envio não tem regra insert. Deixar o bucket público não cria nenhuma.","2026-10-11","\u002Fblog\u002Fstorage-upload-violates-row-level-security\u002Fcard-800x500.png",{"path":638,"title":639,"description":640,"published":641,"category":418,"image":642,"draft":422},"\u002Fblog\u002Fbase44-security-scan","Scan de segurança do Base44: o que só ele enxerga","O scan de segurança do Base44 verifica sete tipos de problema por dentro. Esta é a metade que ele lê e mais ninguém, e a metade que ele nunca olha.","2026-10-10","\u002Fblog\u002Fbase44-security-scan\u002Fcard-800x500.png",{"path":644,"title":645,"description":646,"published":647,"category":418,"image":648,"draft":422},"\u002Fblog\u002Fapi-key-leaked-what-to-do","Sua chave de API vazou. A ordem em que agir","Uma chave de API vazou e você não sabe o que fazer primeiro. Nem toda chave no seu frontend é um vazamento, e a ordem importa mais que a pressa.","2026-10-09","\u002Fblog\u002Fapi-key-leaked-what-to-do\u002Fcard-800x500.png",{"path":650,"title":651,"description":652,"published":653,"category":418,"image":654,"draft":422},"\u002Fblog\u002Finfinite-recursion-in-policy-for-relation","\"Infinite recursion detected in policy\" sem desligar o RLS","\"Infinite recursion detected in policy for relation\" significa que a sua policy perguntou à tabela que ela protege. Veja como quebrar o círculo.","2026-10-08","\u002Fblog\u002Finfinite-recursion-in-policy-for-relation\u002Fcard-800x500.png",{"path":656,"title":657,"description":658,"published":659,"category":418,"image":660,"draft":422},"\u002Fblog\u002Fno-api-key-found-in-request","\"No API key found in request\" no Supabase, e a correção errada","\"No API key found in request\" significa que sua requisição chegou ao Supabase sem chave. Quase toda resposta aponta para as regras do seu banco.","2026-10-07","\u002Fblog\u002Fno-api-key-found-in-request\u002Fcard-800x500.png",{"path":662,"title":663,"description":664,"published":665,"category":418,"image":666,"draft":422},"\u002Fblog\u002Fis-base44-safe","O Base44 é seguro? O que vimos em 5.442 apps Base44","O Base44 é seguro? Rodamos nove verificações em 5.442 apps Base44 no ar. Quase todas tiraram B por motivos que o dono nunca escolheu.","2026-10-06","\u002Fblog\u002Fis-base44-safe\u002Fcard-800x500.png",{"path":668,"title":669,"description":670,"published":671,"category":418,"image":672,"draft":422},"\u002Fblog\u002Fmove-a-secret-to-an-edge-function","Esconder uma chave de API: mova para uma Edge Function do Supabase","Esconder uma chave de API é tirá-la do navegador, e uma Edge Function do Supabase é o menor lugar para guardá-la. Dois passos em volta pesam mais.","2026-10-05","\u002Fblog\u002Fmove-a-secret-to-an-edge-function\u002Fcard-800x500.png",{"path":674,"title":675,"description":676,"published":677,"category":418,"image":678,"draft":422},"\u002Fblog\u002Fenv-file-exposed-on-your-server","Seu arquivo .env está exposto? Os doze caminhos para testar","Seu arquivo .env está exposto no seu próprio servidor web? Doze endereços dizem isso em um minuto, e um acerto significa que tudo nele já é público.","2026-10-04","\u002Fblog\u002Fenv-file-exposed-on-your-server\u002Fcard-800x500.png",{"path":680,"title":681,"description":682,"published":683,"category":418,"image":684,"draft":422},"\u002Fblog\u002Fis-v0-safe","Segurança do v0: os 1.790 aplicativos v0 escaneados tiraram A","A segurança do v0 medida em 1.790 aplicativos v0 no ar: todos tiraram A. Só 17 citavam um banco de dados, e é sobretudo isso que esse A mede.","2026-10-03","\u002Fblog\u002Fis-v0-safe\u002Fcard-800x500.png",{"path":686,"title":687,"description":688,"published":689,"category":418,"image":690,"draft":422},"\u002Fblog\u002Fis-bolt-safe","O Bolt é seguro? O que vimos em 1.123 aplicativos Bolt","O Bolt é seguro? Passamos 1.123 aplicativos Bolt no ar por nove verificações. A hospedagem saiu limpa. Os achados: chaves e tabelas abertas nos aplicativos.","2026-10-02","\u002Fblog\u002Fis-bolt-safe\u002Fcard-800x500.png",{"path":692,"title":693,"description":694,"published":695,"category":418,"image":696,"draft":422},"\u002Fblog\u002Fis-supabase-down-or-your-app","O Supabase caiu ou o problema é o seu app? Como saber","O Supabase caiu ou o problema é o seu app? Um projeto pausado, um banco cheio e um erro seu parecem iguais. Quatro verificações separam os casos.","2026-10-01","\u002Fblog\u002Fis-supabase-down-or-your-app\u002Fcard-800x500.png",{"path":698,"title":699,"description":700,"published":701,"category":418,"image":702,"draft":422},"\u002Fblog\u002Fdoes-supabase-encrypt-my-data","O Supabase criptografa meus dados? Sim. Veja o que isso impede","O Supabase criptografa os dados? Sim: AES-256 em repouso, TLS em trânsito, SOC 2 e ISO 27001. O que cada um cobre, e o vazamento que nenhum deles impede.","2026-09-30","\u002Fblog\u002Fdoes-supabase-encrypt-my-data\u002Fcard-800x500.png",{"path":704,"title":705,"description":706,"published":707,"category":418,"image":708,"draft":422},"\u002Fblog\u002Fsupabase-free-plan-limits","O Supabase é gratuito? Sim, com estes limites e sem backups","Sim: o plano gratuito do Supabase vai até 500 MB de banco e 5 GB de egress, sem nenhum backup. O que para em cada limite e o que muda no Pro de $25.","2026-09-29","\u002Fblog\u002Fsupabase-free-plan-limits\u002Fcard-800x500.png",{"path":710,"title":711,"description":712,"published":713,"category":527,"image":714,"draft":422},"\u002Fblog\u002Ftest-your-supabase-backup","Teste o backup do seu Supabase antes do dia em que precisar","Como testar o backup do seu Supabase: restaurar num projeto de teste, contar as linhas, entrar e procurar a linha que falta num arquivo cortado.","2026-09-28","\u002Fblog\u002Ftest-your-supabase-backup\u002Fcard-800x500.png",{"path":716,"title":717,"description":718,"published":719,"category":527,"image":720,"draft":422},"\u002Fblog\u002Fsupabase-backup-github-action","Backup grátis do Supabase com uma GitHub Action, e a pegadinha","Um backup do Supabase com GitHub Action é grátis e serve para muitos apps. O workflow, a connection string certa e o egress de cada execução.","2026-09-27","\u002Fblog\u002Fsupabase-backup-github-action\u002Fcard-800x500.png",{"path":722,"title":723,"description":724,"published":725,"category":527,"image":726,"draft":422},"\u002Fblog\u002Fdownload-your-supabase-backup","Por que você não consegue baixar seu backup do Supabase","Você não consegue baixar seu backup do Supabase num projeto atual, porque a cópia diária é um snapshot físico. Como conferir e como ter uma cópia só sua.","2026-09-26","\u002Fblog\u002Fdownload-your-supabase-backup\u002Fcard-800x500.png",{"path":728,"title":729,"description":730,"published":725,"category":418,"image":731,"draft":422},"\u002Fblog\u002Fsupabase-permission-denied-for-table","Supabase \"permission denied for table\": o grant que falta","A partir de 30 de outubro, uma tabela nova no Supabase responde \"permission denied for table\" até receber um grant. O e-mail mostra só metade.","\u002Fblog\u002Fsupabase-permission-denied-for-table\u002Fcard-800x500.png",{"path":733,"title":734,"description":735,"published":736,"category":418,"image":737,"draft":422},"\u002Fblog\u002Fopen-api-endpoint-exposed","Um endpoint de API aberto é um problema? Leia o JSON","Seu scan apontou um endpoint de API aberto. Se isso importa depende do que voltou, e a maioria dos que encontramos era da própria plataforma.","2026-09-25","\u002Fblog\u002Fopen-api-endpoint-exposed\u002Fcard-800x500.png",{"path":739,"title":740,"description":741,"published":742,"category":418,"image":743,"draft":422},"\u002Fblog\u002Flovable-security-scan","Escaneamento de segurança do Lovable: o que ele não prova","Escaneamento de segurança do Lovable: o que o Quick scan e o Deep scan checam, quando cada um roda, e a única coisa que nenhum escaneamento por dentro prova.","2026-09-24","\u002Fblog\u002Flovable-security-scan\u002Fcard-800x500.png",{"path":745,"title":746,"description":747,"published":748,"category":527,"image":749,"draft":422},"\u002Fblog\u002Fsupabase-backup-auth-users","Por que seu dump do Supabase não tem usuários dentro","Rode supabase db dump sozinho e você recebe a forma do seu banco e nenhuma das linhas dele, sem o schema auth onde seus usuários moram.","2026-09-23","\u002Fblog\u002Fsupabase-backup-auth-users\u002Fcard-800x500.png",{"path":751,"title":752,"description":753,"published":754,"category":418,"image":755,"draft":422},"\u002Fblog\u002Fdomain-and-certificate-expiry","Domínio expirado, site fora do ar: o que acontece agora","Seu domínio expirou e seu site está fora do ar. O relógio que começa a correr, por que o certificado é o problema menor, e como conferir os dois.","2026-09-22","\u002Fblog\u002Fdomain-and-certificate-expiry\u002Fcard-800x500.png",{"path":757,"title":758,"description":759,"published":760,"category":418,"image":761,"draft":422},"\u002Fblog\u002Fis-lovable-safe","O Lovable é seguro? O que vimos em 18.554 aplicativos Lovable","O Lovable é seguro? Passamos 18.554 aplicativos Lovable no ar por nove verificações. A plataforma foi a mais limpa de cinco. Os achados estavam nos aplicativos.","2026-09-21","\u002Fblog\u002Fis-lovable-safe\u002Fcard-800x500.png",{"path":763,"title":764,"description":765,"published":766,"category":418,"image":767,"draft":422},"\u002Fblog\u002Fvibe-coded-app-security-checklist","O checklist de segurança do vibe coding, em nove verificações","Um checklist de segurança do vibe coding com nove itens, cada um verificável no seu app de fora por qualquer pessoa, e cada um com um teste de uma linha.","2026-09-20","\u002Fblog\u002Fvibe-coded-app-security-checklist\u002Fcard-800x500.png",{"path":769,"title":770,"description":771,"published":772,"category":418,"image":773,"draft":422},"\u002Fblog\u002Fstripe-secret-key-in-frontend","Uma chave secreta da Stripe no frontend pode mover dinheiro","Uma chave secreta da Stripe exposta no seu frontend pode reembolsar, cobrar e ler cada ficha de cliente que você tem. Sua chave pk_live_ é que deve estar aí.","2026-09-19","\u002Fblog\u002Fstripe-secret-key-in-frontend\u002Fcard-800x500.png",{"path":775,"title":776,"description":777,"published":778,"category":418,"image":779,"draft":422},"\u002Fblog\u002Fvite-and-next-public-env-vars","Variáveis de ambiente do Vite expostas: o prefixo diz publique isto","Variáveis de ambiente do Vite expostas no seu app: fizeram o que o prefixo pediu. VITE_ e NEXT_PUBLIC_ significam publique isto, e a IA nunca soube o custo.","2026-09-18","\u002Fblog\u002Fvite-and-next-public-env-vars\u002Fcard-800x500.png",{"path":781,"title":782,"description":783,"published":784,"category":418,"image":785,"draft":422},"\u002Fblog\u002Fbase44-source-maps","Segurança no Base44: o que um scan aponta e o que é seu para corrigir","Segurança no Base44 em 5.438 apps escaneados: três achados em quase todos são da plataforma, o source map é o selo do Base44, e a sua parte é uma lista curta.","2026-09-17","\u002Fblog\u002Fbase44-source-maps\u002Fcard-800x500.png",{"path":787,"title":788,"description":789,"published":790,"category":418,"image":791,"draft":422},"\u002Fblog\u002Fis-cursor-ai-safe","O Cursor AI é seguro? O editor, o código e o app que você publicou","O Cursor AI é seguro? Três perguntas em uma busca: o que o Cursor guarda, o que o código que ele escreve erra, e se o app que você publicou está aberto.","2026-09-16","\u002Fblog\u002Fis-cursor-ai-safe\u002Fcard-800x500.png",{"path":793,"title":794,"description":795,"published":796,"category":418,"image":797,"draft":422},"\u002Fblog\u002Fis-replit-safe","O Replit é seguro? O que vimos em 3.042 aplicativos Replit no ar","O Replit é seguro? Passamos 3.042 aplicativos Replit no ar por nove verificações externas. Os achados estavam no aplicativo publicado, não no host.","2026-09-15","\u002Fblog\u002Fis-replit-safe\u002Fcard-800x500.png",{"path":799,"title":800,"description":801,"published":802,"category":527,"image":803,"draft":422},"\u002Fblog\u002Fsupabase-storage-backup","Supabase storage backup: sua cópia do banco não tem nenhum arquivo","Um Supabase storage backup é uma tarefa à parte. Os backups do banco guardam a lista dos seus arquivos e nenhum deles, então cada upload fica quebrado.","2026-09-14","\u002Fblog\u002Fsupabase-storage-backup\u002Fcard-800x500.png",{"path":805,"title":806,"description":807,"published":808,"category":527,"image":809,"draft":422},"\u002Fblog\u002Fsupabase-point-in-time-recovery","Point-in-time recovery do Supabase: preço e limites","O point-in-time recovery do Supabase rebobina seu banco para qualquer segundo da última semana. Custa $100 por mês além do Pro e cobre só o banco.","2026-09-13","\u002Fblog\u002Fsupabase-point-in-time-recovery\u002Fcard-800x500.png",{"path":811,"title":812,"description":813,"published":814,"category":527,"image":815,"draft":422},"\u002Fblog\u002Fsupabase-project-paused-recover","Projeto Supabase pausado? Seus dados continuam lá","O Supabase pausou seu projeto depois de uma semana sem atividade. Nada foi apagado, Restaurar fica ao lado do nome e você tem um ano antes disso mudar.","2026-09-12","\u002Fblog\u002Fsupabase-project-paused-recover\u002Fcard-800x500.png",{"path":817,"title":818,"description":819,"published":820,"category":418,"image":821,"draft":422},"\u002Fblog\u002Fsafest-ai-app-builder","Qual builder de apps com IA é mais seguro? 30.998 apps testados","Qual builder de apps com IA é mais seguro? Escaneamos 30.998 apps no ar do Lovable, Base44, Replit, v0 e Bolt. O builder não é o que decide sua nota.","2026-09-11","\u002Fblog\u002Fsafest-ai-app-builder\u002Fcard-800x500.png",{"path":823,"title":824,"description":825,"published":826,"category":418,"image":827,"draft":422},"\u002Fblog\u002Fenable-rls-on-every-supabase-table","Ative Row Level Security em toda tabela do Supabase e comprove","Ativar Row Level Security no Supabase sem política fecha a tabela por completo. Uma política sem a chave ligada não faz nada. Aqui está o SQL, e o teste.","2026-09-10","\u002Fblog\u002Fenable-rls-on-every-supabase-table\u002Fcard-800x500.png",{"path":829,"title":830,"description":831,"published":832,"category":418,"image":833,"draft":422},"\u002Fblog\u002Fsupabase-rls-disabled-in-public","Supabase \"RLS disabled in public\": o que o aviso não vê","O Supabase marca \"RLS disabled in public\" como erro. Ele não diz nada sobre a política de leitura que deixa a sua tabela igualmente aberta.","2026-09-09","\u002Fblog\u002Fsupabase-rls-disabled-in-public\u002Fcard-800x500.png",{"path":835,"title":836,"description":837,"published":838,"category":418,"image":839,"draft":422},"\u002Fblog\u002Frotate-supabase-service-role-key","Como rotacionar uma chave service_role do Supabase vazada","O Supabase manda fechar o vazamento primeiro. Outros guias mandam rotacionar agora. O que vale depende de para onde a sua chave service_role vazou.","2026-09-08","\u002Fblog\u002Frotate-supabase-service-role-key\u002Fcard-800x500.png",{"path":841,"title":842,"description":843,"published":844,"category":418,"image":845,"draft":422},"\u002Fblog\u002Fvibe-coding-security-scanners-compared","Scanners de segurança para vibe coding comparados, o nosso incluído","O melhor scanner de segurança para vibe coding depende de três perguntas que nenhuma lista de recursos responde. Oito ferramentas comparadas, com preços.","2026-09-07","\u002Fblog\u002Fvibe-coding-security-scanners-compared\u002Fcard-800x500.png",{"path":847,"title":848,"description":849,"published":850,"category":418,"image":851,"draft":422},"\u002Fblog\u002Fsupabase-security-checker","Supabase security checker: faça você mesmo as cinco verificações","Um Supabase security checker lê o seu app publicado em vez das configurações do projeto. Aqui estão as cinco verificações e como fazer cada uma sozinho.","2026-09-06","\u002Fblog\u002Fsupabase-security-checker\u002Fcard-800x500.png",{"path":853,"title":854,"description":855,"published":856,"category":418,"image":857,"draft":422},"\u002Fblog\u002Fvibe-coding-security-scanner","Scanner de segurança para vibe coding: o que ele não vê","Um scanner de segurança para vibe coding lê seu app no ar, de fora. O que isso cobre, as quatro coisas que ele não consegue ver e como ler o resultado.","2026-09-05","\u002Fblog\u002Fvibe-coding-security-scanner\u002Fcard-800x500.png",{"path":859,"title":860,"description":861,"published":862,"category":418,"image":863,"draft":422},"\u002Fblog\u002Fmissing-security-headers","Cabeçalhos de segurança faltando: quando isso importa","Cabeçalhos de segurança faltando é o achado que nosso scanner mais imprime. Contra o que eles protegem e quando são a linha menos urgente do relatório.","2026-09-04","\u002Fblog\u002Fmissing-security-headers\u002Fcard-800x500.png",{"path":865,"title":866,"description":867,"published":868,"category":418,"image":869,"draft":422},"\u002Fblog\u002Fopenai-api-key-exposed-in-frontend","Sua chave de API da OpenAI está exposta no frontend. Troque-a.","Uma chave de API da OpenAI exposta no frontend não pode ser presa a um domínio. Troque-a hoje, mova a chamada para o seu servidor e limite o gasto.","2026-09-03","\u002Fblog\u002Fopenai-api-key-exposed-in-frontend\u002Fcard-800x500.png",{"path":871,"title":872,"description":873,"published":874,"category":418,"image":875,"draft":422},"\u002Fblog\u002Fwhat-secrets-leak-from-vibe-coded-apps","Chave de API exposta no frontend: o que 30.998 apps entregam","Uma chave de API exposta no seu frontend costuma ser uma chave do Google Maps. Escaneamos 30.998 apps vibe-coded e contamos quais segredos vazam de verdade.","2026-09-02","\u002Fblog\u002Fwhat-secrets-leak-from-vibe-coded-apps\u002Fcard-800x500.png",{"path":877,"title":878,"description":879,"published":880,"category":527,"image":881,"draft":422},"\u002Fblog\u002Fsupabase-backup-tools-compared","Ferramentas de backup do Supabase comparadas, a nossa incluída","Quatro tipos de ferramenta de backup do Supabase, o que cada uma copia de verdade e quando uma GitHub Action gratuita ganha de pagar, nós inclusive.","2026-09-01","\u002Fblog\u002Fsupabase-backup-tools-compared\u002Fcard-800x500.png",{"path":883,"title":884,"description":885,"published":886,"category":418,"image":887,"draft":422},"\u002Fblog\u002Freplit-secrets-explained","Como usar secrets no Replit, e o que ainda assim é publicado","Como usar secrets no Replit: adicionar um, ler de volta e resolver as duas causas do undefined. E as chaves que a ferramenta Secrets não consegue proteger.","2026-08-31","\u002Fblog\u002Freplit-secrets-explained\u002Fcard-800x500.png",{"path":889,"title":890,"description":891,"published":892,"category":527,"image":893,"draft":422},"\u002Fblog\u002Fback-up-supabase-free-tier","Backups do plano gratuito do Supabase: como fazer sem terminal","No plano gratuito do Supabase não existe backup nenhum: a cópia é você que faz. Como fazer uma pelo painel e o que a rota do CSV deixa para trás.","2026-08-30","\u002Fblog\u002Fback-up-supabase-free-tier\u002Fcard-800x500.png",{"path":895,"title":896,"description":897,"published":898,"category":418,"image":899,"draft":422},"\u002Fblog\u002Fis-supabase-secure","O Supabase é seguro? É. Seu projeto é outra pergunta","O Supabase é seguro? A plataforma é auditada, criptografada e passa por pentests. A documentação deles diz onde isso termina e começam suas configurações.","2026-08-29","\u002Fblog\u002Fis-supabase-secure\u002Fcard-800x500.png",{"path":901,"title":902,"description":903,"published":904,"category":418,"image":905,"draft":422},"\u002Fblog\u002Fwhere-to-find-supabase-api-keys","Onde ficam as chaves de API do Supabase: anon, service_role e URL","A URL do projeto, a chave anon e a chave service_role ficam todas numa página do painel. Aqui está onde ela fica, e qual dos quatro valores vai no seu app.","2026-08-28","\u002Fblog\u002Fwhere-to-find-supabase-api-keys\u002Fcard-800x500.png",{"path":907,"title":908,"description":909,"published":910,"category":418,"image":911,"draft":422},"\u002Fblog\u002Fnew-row-violates-row-level-security-policy","New row violates row-level security policy no Supabase. E agora?","\"New row violates row-level security policy\" significa que o Supabase recusou uma escrita. O conserto rápido reabre a tabela para qualquer um.","2026-08-27","\u002Fblog\u002Fnew-row-violates-row-level-security-policy\u002Fcard-800x500.png",{"path":913,"title":914,"description":915,"published":916,"category":418,"image":917,"draft":422},"\u002Fblog\u002Fcors-wildcard-security-risk","Um curinga CORS é um risco de segurança? Quase nunca.","Um curinga CORS é um risco de segurança? Em geral é o padrão do seu builder e não entrega nada que o seu servidor já não desse a qualquer um que pedisse.","2026-08-26","\u002Fblog\u002Fcors-wildcard-security-risk\u002Fcard-800x500.png",{"path":919,"title":920,"description":921,"published":922,"category":527,"image":923,"draft":422},"\u002Fblog\u002Fsupabase-branching-is-not-a-backup","Branching do Supabase não é backup. Ele só anda para a frente.","Por que o branching do Supabase não é backup: um branch começa sem os seus dados e um merge só leva o esquema. Para que ele serve e o que usar no lugar.","2026-08-25","\u002Fblog\u002Fsupabase-branching-is-not-a-backup\u002Fcard-800x500.png",{"path":925,"title":926,"description":927,"published":928,"category":527,"image":929,"draft":422},"\u002Fblog\u002Fhow-to-restore-a-supabase-backup","Como restaurar um backup do Supabase, e o que quebra depois","Como restaurar um backup do Supabase pelo painel ou por um arquivo de dump, o que a restauração substitui e por que o seu app pode continuar quebrado no fim.","2026-08-24","\u002Fblog\u002Fhow-to-restore-a-supabase-backup\u002Fcard-800x500.png",{"path":402,"title":931,"description":932,"published":933,"category":418,"image":934,"draft":422},"Seu bucket do Supabase Storage é público. Isso é um problema?","Um bucket público do Supabase Storage significa que quem tem a URL de um arquivo pode abri-lo. Não significa que alguém possa listar o que está lá dentro.","2026-08-23","\u002Fblog\u002Fsupabase-storage-bucket-public\u002Fcard-800x500.png",{"path":936,"title":937,"description":938,"published":939,"category":418,"image":940,"draft":422},"\u002Fblog\u002Fgoogle-api-key-exposed-in-frontend","Uma chave de API do Google no frontend é um problema?","Uma chave de API do Google exposta no seu frontend é a chave que nosso scanner mais encontra, e quase sempre está tudo bem. Um ajuste gratuito decide isso.","2026-08-22","\u002Fblog\u002Fgoogle-api-key-exposed-in-frontend\u002Fcard-800x500.png",{"path":942,"title":943,"description":944,"published":945,"category":527,"image":946,"draft":422},"\u002Fblog\u002Fai-agent-deleted-my-database","Um agente de IA apagou meus dados do Supabase. O que eu recupero?","Um agente de IA apagou dados do seu banco. O que você recupera já estava decidido antes de ele rodar, e os próximos minutos decidem o resto.","2026-08-21","\u002Fblog\u002Fai-agent-deleted-my-database\u002Fcard-800x500.png",{"path":948,"title":949,"description":950,"published":951,"category":418,"image":952,"draft":422},"\u002Fblog\u002Fcan-anyone-read-your-supabase-database","Qualquer um consegue ler seu banco Supabase? Testamos 3.680 apps","Qualquer um consegue ler seu banco de dados Supabase sem fazer login? Escaneamos 30.998 apps no ar criadas com builders de IA e medimos quantas dizem que sim.","2026-08-18","\u002Fblog\u002Fcan-anyone-read-your-supabase-database\u002Fcard-800x500.png",{"path":954,"title":955,"description":956,"published":951,"category":418,"image":957,"draft":422},"\u002Fblog\u002Fsource-maps-exposed-in-production","Source maps expostos: seu app está publicando o código original","Um source map exposto deixa qualquer um ler o código original do seu app, comentários incluídos. A verificação de 30 segundos e o que importa de verdade.","\u002Fblog\u002Fsource-maps-exposed-in-production\u002Fcard-800x500.png",{"path":959,"title":960,"description":961,"published":962,"category":418,"image":963,"draft":422},"\u002Fblog\u002Fsupabase-new-api-keys","Supabase publishable key: é a mesma coisa que a anon key?","O Supabase trocou anon e service_role por chaves publicáveis e secretas. Qual delas pertence ao seu app e qual nunca deve estar lá?","2026-08-12","\u002Fblog\u002Fsupabase-new-api-keys\u002Fcard-800x500.png",{"path":965,"title":966,"description":967,"published":968,"category":527,"image":969,"draft":422},"\u002Fblog\u002Fdoes-supabase-back-up-my-database","O Supabase faz backup do meu banco de dados? Depende do plano.","O Supabase faz backup do seu banco de dados? Todo dia nos planos pagos, e nada no gratuito. Como descobrir o que você tem e o que essa cópia não cobre.","2026-08-11","\u002Fblog\u002Fdoes-supabase-back-up-my-database\u002Fcard-800x500.png",{"path":971,"title":972,"description":973,"published":974,"category":418,"image":975,"draft":422},"\u002Fblog\u002Fsupabase-rls-on-but-table-still-public","O Supabase Row Level Security está ligado. A tabela continua pública.","Ligar o Supabase Row Level Security não protege uma tabela. Quem protege são as políticas, e a que consertou o seu app pode deixar qualquer um entrar.","2026-08-10","\u002Fblog\u002Fsupabase-rls-on-but-table-still-public\u002Fcard-800x500.png",{"path":977,"title":978,"description":979,"published":974,"category":527,"image":980,"draft":422},"\u002Fblog\u002Fversion-history-is-not-a-backup","O histórico de versões não é backup. Ele não desfaz um delete.","Lovable e Bolt guardam um histórico de versões do seu código. Seu banco de dados é um serviço à parte, e voltar atrás não traz os seus dados de volta.","\u002Fblog\u002Fversion-history-is-not-a-backup\u002Fcard-800x500.png",{"path":982,"title":983,"description":984,"published":985,"category":527,"image":986,"draft":422},"\u002Fblog\u002Fthree-ways-to-back-up-a-supabase-database","Três formas de fazer backup de um banco Supabase, e o que falta","O painel, o pg_dump e um serviço gerenciado. O que cada um salva de verdade, o que deixa de fora sem avisar e qual sobrevive a perder a conta.","2026-08-09","\u002Fblog\u002Fthree-ways-to-back-up-a-supabase-database\u002Fcard-800x500.png",{"path":988,"title":989,"description":990,"published":985,"category":418,"image":991,"draft":422},"\u002Fblog\u002Fwhich-api-keys-are-safe-in-your-frontend","Quais chaves de API são seguras no navegador e quais não são","Sua chave anon do Supabase foi feita para ser pública. Sua chave service_role não, e ela ignora todas as regras que você criar. Como diferenciar as duas.","\u002Fblog\u002Fwhich-api-keys-are-safe-in-your-frontend\u002Fcard-800x500.png",1794213649229]