[{"data":1,"prerenderedAt":1238},["ShallowReactive",2],{"blog-pt-supabase-schema-cache-column-error":3,"blog-index-pt":710},{"id":4,"title":5,"body":6,"category":668,"cover":669,"coverAlt":670,"description":671,"draft":672,"extension":673,"faq":674,"image":689,"keywords":690,"meta":699,"navigation":700,"ogTitle":5,"path":701,"published":702,"seo":703,"stem":704,"tldr":705,"updated":702,"__hash__":709},"blog_pt\u002Fblog\u002Fsupabase-schema-cache-column-error.md","Supabase PGRST204: \"Could not find the column in the schema cache\"",{"type":7,"value":8,"toc":654},"minimark",[9,13,24,31,39,44,47,50,73,114,117,123,127,140,149,158,226,238,241,249,256,264,273,277,280,283,289,312,315,339,359,364,368,376,385,401,405,426,439,444,448,451,457,472,475,481,484,488,491,499,502,514,518,521,530,536,550,554,557,565,585,594,612,616,647],[10,11,12],"p",{},"Você pediu ao seu builder para colocar um telefone no formulário de perfil. A\ncoluna está lá no Table Editor. Você clica em Salvar, nada acontece, e o console\ndo navegador mostra isto:",[14,15,20],"pre",{"className":16,"code":18,"language":19},[17],"language-text","{\n  \"code\": \"PGRST204\",\n  \"details\": null,\n  \"hint\": null,\n  \"message\": \"Could not find the 'phoneNumber' column of 'profiles' in the schema cache\"\n}\n","text",[21,22,18],"code",{"__ignoreMap":23},"",[10,25,26,27,30],{},"Supabase \"Could not find the column in the schema cache\" significa que seu app\ntentou salvar um campo que a tabela, do jeito que o PostgREST a enxerga, não tem.\nO PostgREST é a parte do Supabase que transforma as chamadas\n",[21,28,29],{},"supabase.from(...)"," do seu app em consultas ao banco de dados. Ele mantém a\nprópria lista de cada tabela e cada coluna, chamada schema cache, para não\nprecisar perguntar ao banco sobre a estrutura dele a cada requisição.",[10,32,33,34,38],{},"Aqui está a parte que quase toda resposta erra: ",[35,36,37],"strong",{},"ela manda você recarregar o\nschema cache."," No Supabase o cache se recarrega sozinho toda vez que uma tabela\nmuda. Então, se você acabou de adicionar uma coluna e ainda vê esse erro, o cache\né o motivo menos provável. Geralmente é o nome.",[40,41,43],"h2",{"id":42},"o-que-significa-could-not-find-the-column-in-the-schema-cache","O que significa \"Could not find the column in the schema cache\"?",[10,45,46],{},"Uma chave de uma escrita que seu app enviou não tem coluna correspondente naquela\ntabela.",[10,48,49],{},"Pense no schema cache como o painel do saguão de um prédio: uma linha para cada\nescritório, que é uma tabela, e embaixo cada sala, que é uma coluna. Cada\nrequisição do seu app é uma guia de entrega. O PostgREST confere cada linha da\nguia com o painel, e uma sala que o painel não lista é recusada na recepção,\nantes que qualquer coisa chegue aos seus dados.",[10,51,52,53,56,57,60,61,64,65,72],{},"A mensagem nomeia os dois lados dessa comparação. Em ",[21,54,55],{},"Could not find the 'phoneNumber' column of 'profiles' in the schema cache",", ",[21,58,59],{},"phoneNumber"," é o que\nseu app enviou e ",[21,62,63],{},"profiles"," a tabela para onde foi. Outras três coisas estão\nfixadas no\n",[66,67,71],"a",{"href":68,"rel":69},"https:\u002F\u002Fgithub.com\u002FPostgREST\u002Fpostgrest\u002Fblob\u002Fmain\u002Fsrc\u002Flibrary\u002FPostgREST\u002FError.hs",[70],"nofollow","próprio código do PostgREST",":",[74,75,76,84,98],"ul",{},[77,78,79,80,83],"li",{},"o código é ",[21,81,82],{},"PGRST204"," e o status é HTTP 400, o que quer dizer que a própria\nrequisição estava errada",[77,85,86,87,56,90,93,94,97],{},"ele só vem de escritas: ",[21,88,89],{},".insert()",[21,91,92],{},".update()"," e ",[21,95,96],{},".upsert()",". Uma leitura\nque cita uma coluna inexistente falha com outro erro, escrito pelo Postgres",[77,99,100,101,105,106,109,110,113],{},"ele não traz nenhuma dica. Para\n",[66,102,104],{"href":103},"\u002Fblog\u002Fsupabase-relation-does-not-exist","uma tabela que falta",", o PostgREST\nsugere o nome mais parecido que conhece; para uma coluna que falta, ",[21,107,108],{},"hint"," é ",[21,111,112],{},"null",", e\na comparação fica com você",[10,115,116],{},"Cada chave do objeto que você passa para uma dessas três chamadas tem que ser uma\ncoluna daquela tabela, escrita do jeito que a tabela escreve.",[118,119],"diagram",{"alt":120,"caption":121,"src":122},"Uma guia de entrega com três linhas ao lado do painel profiles, que lista quatro salas. Duas linhas da guia levam a salas com o mesmo nome e estão marcadas. A terceira, phoneNumber, termina em âmbar num sinal de diferente ao lado de phone_number.","O PostgREST compara cada chave que seu app envia com as colunas da lista dele, letra por letra. phoneNumber e phone_number são dois nomes diferentes.","\u002Fblog\u002Fsupabase-schema-cache-column-error\u002Fletter-for-letter-1600x700.png",[40,124,126],{"id":125},"causa-1-o-nome-não-bate-letra-por-letra","Causa 1: o nome não bate, letra por letra",[10,128,129,130,56,132,135,136,139],{},"A conferência é exata. Para o PostgREST, ",[21,131,59],{},[21,133,134],{},"phone_number"," e\n",[21,137,138],{},"phonenumber"," são três colunas diferentes, e sua tabela tem no máximo uma delas.",[10,141,142,143,145,146,148],{},"Há dois jeitos comuns de chegar aqui. O primeiro são dois hábitos de nomes que\nse encontram: o JavaScript costuma escrever um campo como ",[21,144,59],{},", e uma\ncoluna do Postgres costuma se chamar ",[21,147,134],{},". O código que seu builder\nescreveu e o SQL que ele rodou podem estar certos cada um do seu lado e mesmo\nassim não bater.",[10,150,151,152,157],{},"O segundo é a armadilha das aspas. Em SQL, um nome digitado sem aspas duplas é\nconvertido para minúsculas. A\n",[66,153,156],{"href":154,"rel":155},"https:\u002F\u002Fwww.postgresql.org\u002Fdocs\u002Fcurrent\u002Fsql-syntax-lexical.html",[70],"documentação do Postgres","\ndiz com todas as letras: \"Quoting an identifier also makes it case-sensitive,\nwhereas unquoted names are always folded to lower case.\"",[159,160,161,177],"table",{},[162,163,164],"thead",{},[165,166,167,171,174],"tr",{},[168,169,170],"th",{},"O que você rodou no SQL Editor",[168,172,173],{},"A coluna que foi criada",[168,175,176],{},"O que seu app tem que enviar",[178,179,180,196,211],"tbody",{},[165,181,182,188,192],{},[183,184,185],"td",{},[21,186,187],{},"alter table profiles add column phone_number text;",[183,189,190],{},[21,191,134],{},[183,193,194],{},[21,195,134],{},[165,197,198,203,207],{},[183,199,200],{},[21,201,202],{},"alter table profiles add column phoneNumber text;",[183,204,205],{},[21,206,138],{},[183,208,209],{},[21,210,138],{},[165,212,213,218,222],{},[183,214,215],{},[21,216,217],{},"alter table profiles add column \"phoneNumber\" text;",[183,219,220],{},[21,221,59],{},[183,223,224],{},[21,225,59],{},[10,227,228,229,231,232,234,235,237],{},"A linha do meio é a que engana. O SQL parece ter criado ",[21,230,59],{},", o código\nenvia ",[21,233,59],{},", e a coluna é ",[21,236,138],{},".",[10,239,240],{},"Para ver os nomes de verdade, abra a tabela no Table Editor e leia os cabeçalhos\ndas colunas, ou rode isto no SQL Editor:",[14,242,247],{"className":243,"code":245,"language":246,"meta":23},[244],"language-sql","select column_name\nfrom information_schema.columns\nwhere table_schema = 'public' and table_name = 'profiles';\n","sql",[21,248,245],{"__ignoreMap":23},[10,250,251,252,255],{},"Depois veja o que seu app enviou. Nas ferramentas de desenvolvedor do navegador,\nabra a aba Rede (Network), clique na requisição que falhou para\n",[21,253,254],{},"\u002Frest\u002Fv1\u002Fprofiles"," e leia o payload dela.",[10,257,258,259,109,261,263],{},"A correção mais segura é mudar o app, porque isso não mexe em nada dos seus\ndados. Peça ao seu builder para usar o nome exato da coluna em todo lugar onde\nesse campo é salvo: \"a coluna em ",[21,260,63],{},[21,262,134],{},"; use esse nome em\ntodo insert e update\". Renomear a coluna em vez disso é uma mudança numa tabela\nem uso, e qualquer outra tela que ainda use o nome antigo quebra na primeira vez\nque rodar.",[10,265,266,267,272],{},"Se você constrói com Lovable, volte no chat procurando uma mudança no banco que\nvocê precisava aprovar. A\n",[66,268,271],{"href":269,"rel":270},"https:\u002F\u002Fdocs.lovable.dev\u002Fintegrations\u002Fsupabase",[70],"documentação de Supabase do Lovable","\ndiz que ele \"writes the SQL, shows it to you, and asks for your approval in the\nproject chat before running it\". Até você aprovar, a coluna não existe, não\nimporta o que o código espere.",[40,274,276],{"id":275},"causa-2-uma-chave-que-nunca-foi-coluna","Causa 2: uma chave que nunca foi coluna",[10,278,279],{},"A requisição leva algo que a tabela nunca deveria guardar: linhas relacionadas\naninhadas dentro do insert, ou um campo que o formulário guarda para si.",[10,281,282],{},"O insert aninhado é o que as pessoas esperam que funcione:",[14,284,287],{"className":285,"code":286,"language":19},[17],"await supabase.from('orders').insert({\n  customer_id: user.id,\n  total: 42,\n  order_items: [{ product_id: 7, quantity: 2 }],\n})\n",[21,288,286],{"__ignoreMap":23},[10,290,291,292,295,296,299,300,305,306,311],{},"Isso falha com ",[21,293,294],{},"Could not find the 'order_items' column of 'orders' in the schema cache",". Ler o mesmo formato funciona: ",[21,297,298],{},".select('*, order_items(*)')","\ndevolve um pedido com os itens dele, então parece que o caminho inverso também\ndeveria funcionar. O PostgREST lê cada chave de uma escrita como coluna da única\ntabela para onde a requisição vai. Um usuário do Supabase\n",[66,301,304],{"href":302,"rel":303},"https:\u002F\u002Fgithub.com\u002Fsupabase\u002Fsupabase\u002Fissues\u002F50816",[70],"relatou isso como bug",", e a\nresposta, antes de a issue ser fechada em 18 de outubro de 2026, foi que inserts\naninhados são um recurso que falta. O pedido por eles está aberto no\n",[66,307,310],{"href":308,"rel":309},"https:\u002F\u002Fgithub.com\u002FPostgREST\u002Fpostgrest\u002Fissues\u002F818",[70],"tracker do PostgREST"," desde\nfevereiro de 2017.",[10,313,314],{},"Outras duas formas do mesmo problema:",[74,316,317,330],{},[77,318,319,320,322,323,326,327,329],{},"uma linha lida junto com as linhas relacionadas, editada num formulário e\ndevolvida inteira em ",[21,321,92],{},", de modo que o ",[21,324,325],{},"order_items"," ou o ",[21,328,63],{},"\nanexado vai junto",[77,331,332,333,335,336],{},"o estado inteiro de um formulário passado direto para ",[21,334,89],{},", com campos\nque o formulário precisa e a tabela não, como ",[21,337,338],{},"confirmPassword",[10,340,341,342,345,346,349,350,353,354,358],{},"A correção é gravar cada tabela separadamente, o pai primeiro. Insira o pedido e\npeça o id dele de volta com ",[21,343,344],{},".select('id').single()",", depois insira os itens com\nesse ",[21,347,348],{},"order_id",". São duas requisições, então se a segunda falhar o pedido fica\nsalvo sem os itens. Quando isso não pode acontecer nunca, coloque os dois inserts\nnuma função do Postgres e chame com ",[21,351,352],{},".rpc()",", que a resposta naquela issue chama\nde padrão. Aí tudo é salvo, ou nada. Se essa chamada responder PGRST202,\n",[66,355,357],{"href":356},"\u002Fblog\u002Fsupabase-function-not-found","a versão deste erro para funções"," explica\npor quê.",[118,360],{"alt":361,"caption":362,"src":363},"Faixa de cima: uma guia com uma segunda guia aninhada dentro vai para o painel orders. As duas linhas simples estão marcadas, e a aninhada para num X âmbar ligado a uma placa com PGRST204 e 400. Faixa de baixo: duas guias enviadas uma depois da outra, numeradas 1 e 2, cada uma para o próprio painel, as duas marcadas.","Uma guia aninhada é lida como mais uma coluna da primeira tabela. Enviadas separadamente, o pai primeiro, cada uma encontra o próprio painel.","\u002Fblog\u002Fsupabase-schema-cache-column-error\u002Fa-key-that-is-not-a-column-1600x720.png",[40,365,367],{"id":366},"causa-3-a-mudança-foi-para-outro-projeto","Causa 3: a mudança foi para outro projeto",[10,369,370,371,375],{},"A coluna existe, num banco com que seu app nunca conversa. Uma conta do Supabase\npode ter vários projetos, e uma\n",[66,372,374],{"href":373},"\u002Fblog\u002Fsupabase-branching-is-not-a-backup","branch é um projeto separado"," com o\npróprio banco. Uma coluna adicionada no SQL Editor do projeto errado muda o\npainel de outro prédio.",[10,377,378,379,384],{},"Na\n",[66,380,383],{"href":381,"rel":382},"https:\u002F\u002Fgithub.com\u002Fsupabase\u002Fsupabase\u002Fissues\u002F42183",[70],"issue #42183"," do Supabase,\num relato de que o cache \"does not update\" não importa o que se tentasse, um dos\ndesenvolvedores do PostgREST respondeu que o relato citava duas referências de\nprojeto diferentes, e pediu para confirmar que a mudança tinha sido feita no\nprojeto para onde as requisições iam.",[10,386,387,388,391,392,395,396,400],{},"A conferência usa dois endereços. Seu app chama\n",[21,389,390],{},"https:\u002F\u002F\u003Creference>.supabase.co",", que você vê em qualquer requisição na aba\nRede. O painel mostra o projeto em que você está em\n",[21,393,394],{},"supabase.com\u002Fdashboard\u002Fproject\u002F\u003Creference>",". As duas referências têm que ser a\nmesma sequência de caracteres.\n",[66,397,399],{"href":398},"\u002Fblog\u002Fwhere-to-find-supabase-api-keys","Qual projeto é o meu"," explica como achar\nquando outra pessoa configurou o Supabase.",[40,402,404],{"id":403},"causa-4-o-cache-está-mesmo-desatualizado","Causa 4: o cache está mesmo desatualizado",[10,406,407,408,411,412,415,416,419,420,425],{},"É o caso raro no Supabase, porque o Supabase recarrega o cache por você. Todo\nbanco do Supabase é configurado com um gatilho de evento, ",[21,409,410],{},"pgrst_ddl_watch",", que\nroda depois de cada mudança na estrutura do banco, ",[21,413,414],{},"ALTER TABLE"," incluído, e\nenvia ",[21,417,418],{},"NOTIFY pgrst, 'reload schema'",": a mensagem que manda o PostgREST\nreconstruir a lista. Dá para ler isso na\n",[66,421,424],{"href":422,"rel":423},"https:\u002F\u002Fgithub.com\u002Fsupabase\u002Fpostgres\u002Fblob\u002Fdevelop\u002Fmigrations\u002Fschema-17.sql",[70],"configuração de banco do Supabase",".\nAdicionar uma coluna no Table Editor ou no SQL Editor repinta o painel sozinho.",[10,427,428,429,434,435,438],{},"Dá errado quando essa mensagem nunca chega. O\n",[66,430,433],{"href":431,"rel":432},"https:\u002F\u002Fsupabase.com\u002Fdocs\u002Fguides\u002Ftroubleshooting\u002Fpostgrest-not-recognizing-new-columns-or-functions-bd75f5",[70],"guia de solução de problemas","\ndo Supabase descreve o caso: \"an underlying Postgres notification queue issue\nprevents PostgREST from receiving cache reload signals after schema changes\". O\nlog do PostgREST mostra então ",[21,436,437],{},"Failed listening for database notifications on the \"pgrst\" channel",", e o painel fica como estava, não importa quantas colunas\nvocê adicione.",[118,440],{"alt":441,"caption":442,"src":443},"Faixa de cima: ALTER TABLE adiciona uma coluna a uma tabela, um sino toca, uma linha marcada NOTIFY pgrst chega ao painel profiles, e o painel ganha a mesma placa nova. Faixa de baixo: a mesma mudança, a linha cortada por um X âmbar, e o painel com um espaço vazio tracejado onde a placa nova deveria estar.","Cada ALTER TABLE no Supabase envia a mensagem de recarga sozinho. Um cache desatualizado quer dizer que essa mensagem não chegou.","\u002Fblog\u002Fsupabase-schema-cache-column-error\u002Fthe-board-repaints-itself-1600x660.png",[40,445,447],{"id":446},"como-recarrego-o-schema-cache-do-supabase","Como recarrego o schema cache do Supabase?",[10,449,450],{},"Rode uma linha no SQL Editor:",[14,452,455],{"className":453,"code":454,"language":246,"meta":23},[244],"NOTIFY pgrst, 'reload schema';\n",[21,456,454],{"__ignoreMap":23},[10,458,459,460,465,466,471],{},"A\n",[66,461,464],{"href":462,"rel":463},"https:\u002F\u002Fsupabase.com\u002Fdocs\u002Fguides\u002Ftroubleshooting\u002Frefresh-postgrest-schema",[70],"página do Supabase sobre isso","\ndiz que você deve ver \"Success. No rows returned\" em Results. É seguro num app\nem uso. A\n",[66,467,470],{"href":468,"rel":469},"https:\u002F\u002Fdocs.postgrest.org\u002Fen\u002Fv14\u002Freferences\u002Fschema_cache.html",[70],"documentação do PostgREST","\ndiz \"Requests will wait until the schema cache reload is done\", então ninguém\nusando o app vê erro enquanto isso.",[10,473,474],{},"Se o problema é a fila de notificações, a mensagem de recarga fica presa do mesmo\njeito que a automática. O guia de solução de problemas dá uma segunda linha para\nesse caso:",[14,476,479],{"className":477,"code":478,"language":246,"meta":23},[244],"select pg_notification_queue_usage();\n",[21,480,478],{"__ignoreMap":23},[10,482,483],{},"Segundo o Supabase, ela faz o PostgREST atualizar o cache e \"does not require a\ndatabase instance or PostgREST service restart\". Depois tente salvar de novo.",[40,485,487],{"id":486},"quando-recarregar-não-resolve","Quando recarregar não resolve",[10,489,490],{},"Reinicie o projeto e, se o erro sobreviver a isso, volte às causas 1 a 3.",[10,492,493,494,498],{},"Um reinício sempre dá ao PostgREST uma lista nova. O mesmo desenvolvedor do\nPostgREST escreveu na #42183 que um PostgREST reiniciado \"won't go live if it\ndoesn't load a new schema cache\". Restart project fica em Project Settings,\ndepois General, e\n",[66,495,497],{"href":496},"\u002Fblog\u002Fis-supabase-down-or-your-app","como reiniciar um projeto do Supabase","\nmostra o passo a passo, incluindo os poucos minutos em que ele fica fora do ar.",[10,500,501],{},"Então um erro que sobrevive a um reinício vem de uma lista nova e exata: aquela\ntabela, naquele projeto, não tem uma coluna com esse nome. A própria #42183,\naberta em janeiro de 2026 por alguém que já tinha tentado recarregar, reiniciar e\napagar e recriar a coluna, ainda estava aberta quando a lemos em 21 de outubro de\n2026. A resposta do desenvolvedor ali também sugeria atualizar para o PostgREST\n14 nas configurações de Infrastructure do projeto.",[10,503,504,505,508,509,513],{},"Risque apagar e recriar da sua lista. ",[21,506,507],{},"alter table … drop column"," apaga cada\nvalor guardado naquela coluna, e a coluna nova com o mesmo nome começa vazia. Se\nvocê está prestes a mudar uma tabela em que usuários de verdade gravam dados,\nguarde uma cópia do banco de antes da mudança. O\n",[66,510,512],{"href":511},"\u002Fsupabase-backups","Reeve Care"," faz uma num cronograma e a guarda\ncriptografada, no armazenamento próprio da Reeve na UE.",[40,515,517],{"id":516},"mantendo-seus-tipos-gerados-em-dia","Mantendo seus tipos gerados em dia",[10,519,520],{},"Gere de novo seus tipos de TypeScript depois de cada mudança numa tabela, e um\nnome de coluna escrito errado pode aparecer no editor antes de chegar ao site no\nar.",[10,522,523,524,529],{},"O Supabase monta o arquivo a partir das suas colunas reais, pelo painel ou com\num comando do\n",[66,525,528],{"href":526,"rel":527},"https:\u002F\u002Fsupabase.com\u002Fdocs\u002Fguides\u002Fapi\u002Frest\u002Fgenerating-types",[70],"guia de geração de tipos","\ndele:",[14,531,534],{"className":532,"code":533,"language":19},[17],"npx supabase gen types typescript --project-id \"$PROJECT_REF\" --schema public > database.types.ts\n",[21,535,533],{"__ignoreMap":23},[10,537,538,539,542,543,546,547,549],{},"Quando o cliente é criado com esses tipos, ",[21,540,541],{},"createClient\u003CDatabase>(…)",", o tipo\n",[21,544,545],{},"Insert"," de cada tabela lista as colunas que o ",[21,548,89],{}," aceita. Uma coluna\nescrita errado num objeto escrito por inteiro dentro da chamada é então marcada\ncomo erro antes de você publicar. A documentação do Lovable diz que ele\n\"regenerates the TypeScript types your app uses\" depois de uma mudança no banco.\nUm arquivo de tipos gerado antes da sua última mudança na tabela ainda lista as\ncolunas antigas.",[40,551,553],{"id":552},"mudar-uma-tabela-em-uso-sem-perder-o-que-está-nela","Mudar uma tabela em uso sem perder o que está nela",[10,555,556],{},"Guarde uma cópia de antes da mudança e saiba na hora se o app continua\nrespondendo depois.",[10,558,559],{},[35,560,561,562,564],{},"O ",[66,563,512],{"href":511}," guarda uma cópia do seu banco do Supabase:",[74,566,567,570,573,576,579,582],{},[77,568,569],{},"uma cópia criptografada num cronograma, no armazenamento próprio da Reeve na UE, fora da sua conta do Supabase",[77,571,572],{},"a última cópia antes da sua mudança tem as tabelas e colunas como eram, com as linhas",[77,574,575],{},"cada cópia verificada antes de contar, contando as linhas de cada tabela",[77,577,578],{},"também seus arquivos enviados, assim que você conecta uma credencial do Storage",[77,580,581],{},"restauração com um clique, com uma cópia de segurança do estado atual feita antes",[77,583,584],{},"tudo o que o Monitor faz",[10,586,587],{},[35,588,561,589,593],{},[66,590,592],{"href":591},"\u002Fwebsite-monitoring","Reeve Monitor"," continua verificando de fora:",[74,595,596,599,602,609],{},[77,597,598],{},"se o seu app está no ar, verificado a cada minuto, para separar fácil um botão Salvar quebrado de uma queda",[77,600,601],{},"a verificação de segurança completa a cada hora, em até três apps",[77,603,604,605,608],{},"uma mensagem quando um resultado ",[35,606,607],{},"muda",", para que um deploy que muda o que seu app expõe chegue até você sem você ir olhar",[77,610,611],{},"um relatório mensal, em linguagem simples, do que ele viu",[40,613,615],{"id":614},"o-que-fazer-agora","O que fazer agora",[617,618,619],"key-takeaways",{},[74,620,621,624,627,630,633,644],{},[77,622,623],{},"Leia os dois nomes na mensagem: a chave que seu app enviou e a tabela para onde ela foi.",[77,625,626],{},"Compare essa chave com a coluna no Table Editor, letra por letra. Um nome digitado em SQL sem aspas fica salvo em minúsculas.",[77,628,629],{},"Procure chaves que não são colunas: linhas relacionadas aninhadas num insert, ou uma linha inteira devolvida com as linhas relacionadas. Grave cada tabela separadamente, ou coloque as duas escritas numa função.",[77,631,632],{},"Confira se a referência no endereço do Supabase do seu app bate com o projeto que você mudou.",[77,634,635,636,639,640,643],{},"Se tudo isso bater, rode ",[21,637,638],{},"NOTIFY pgrst, 'reload schema';",", depois ",[21,641,642],{},"select pg_notification_queue_usage();",", e só reinicie o projeto se nenhum dos dois ajudar.",[77,645,646],{},"Gere de novo seus tipos de TypeScript depois de cada mudança numa tabela.",[10,648,649,650,653],{},"Comece pelo nome de coluna que a mensagem cita, porque é exatamente o que seu app\nenviou, e o Table Editor mostra exatamente o que a tabela tem. Antes de renomear\nou apagar qualquer coisa numa tabela que as pessoas usam,\n",[66,651,652],{"href":511},"guarde uma cópia do banco"," de antes da mudança.",{"title":23,"searchDepth":655,"depth":655,"links":656},3,[657,659,660,661,662,663,664,665,666,667],{"id":42,"depth":658,"text":43},2,{"id":125,"depth":658,"text":126},{"id":275,"depth":658,"text":276},{"id":366,"depth":658,"text":367},{"id":403,"depth":658,"text":404},{"id":446,"depth":658,"text":447},{"id":486,"depth":658,"text":487},{"id":516,"depth":658,"text":517},{"id":552,"depth":658,"text":553},{"id":614,"depth":658,"text":615},"Noções de segurança","\u002Fblog\u002Fsupabase-schema-cache-column-error\u002Fcover-1200x630.png","Um painel de saguão com um espaço vazio na lista de salas e, na frente, uma guia de entrega com uma linha acesa em âmbar.","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.",false,"md",[675,678,681,683,686],{"q":676,"a":677},"O que significa PGRST204?","PGRST204 é o código que o PostgREST, a parte do Supabase que responde às chamadas do seu app ao banco de dados, dá a uma escrita que cita uma coluna que a tabela não tem. Ele volta com HTTP 400 e a mensagem \"Could not find the 'x' column of 'y' in the schema cache\", em que x é a chave que seu app enviou e y a tabela para onde foi. Inserts, updates e upserts o produzem.",{"q":679,"a":680},"Eu adicionei a coluna e continua falhando. Por quê?","Geralmente é o nome. Confira se seu app envia exatamente o nome salvo (uma coluna adicionada em SQL como phoneNumber, sem aspas, fica salva como phonenumber), se você a adicionou no projeto que o seu app chama, e se nada mais na requisição é uma chave que a tabela não tem. O Supabase recarrega o schema cache sozinho depois de cada ALTER TABLE, então um cache desatualizado é a última coisa a suspeitar.",{"q":447,"a":682},"Rode NOTIFY pgrst, 'reload schema'; no SQL Editor. Se nada mudar, o guia de solução de problemas do Supabase dá um segundo comando, select pg_notification_queue_usage();, para quando as mensagens de recarga ficam presas. As requisições que chegam durante a recarga esperam ela terminar.",{"q":684,"a":685},"Pausar o projeto limpa o cache?","Sim. O PostgREST monta um schema cache novo toda vez que inicia, e retomar um projeto pausado o inicia de novo. Restart project, em Project Settings e depois General, faz o mesmo sem a pausa. Se o erro sobreviver a qualquer um dos dois, o cache estava certo desde o começo: a coluna falta naquela tabela, naquele projeto.",{"q":687,"a":688},"Por que inserts aninhados falham com esse erro?","Porque o PostgREST lê cada chave de um insert como coluna de uma única tabela, e uma chave com linhas relacionadas é uma coluna que ele não encontra. Ler linhas relacionadas numa requisição funciona; gravá-las assim nunca foi suportado. Insira primeiro o pai e depois os filhos com o id dele, ou faça as duas coisas numa função do Postgres chamada com rpc().","\u002Fblog\u002Fsupabase-schema-cache-column-error\u002Fcard-800x500.png",[691,692,693,694,695,696,697,698],"could not find the column in the schema cache","pgrst204","supabase could not find the column of in the schema cache","supabase schema cache não atualiza","notify pgrst reload schema","supabase coluna nova não funciona","recarregar schema cache supabase","supabase insert aninhado",{},true,"\u002Fblog\u002Fsupabase-schema-cache-column-error","2026-10-21",{"title":5,"description":671},"blog\u002Fsupabase-schema-cache-column-error",[706,707,708],"Supabase \"Could not find the column in the schema cache\" (PGRST204) significa que seu app tentou salvar um campo que a tabela não lista. O PostgREST compara cada chave de um insert ou update com a própria cópia do seu schema, letra por letra.","A causa de costume é o nome: phoneNumber enviado para uma coluna chamada phone_number, ou uma chave que nunca foi coluna, como linhas relacionadas aninhadas dentro de um insert.","O Supabase recarrega essa cópia sozinho sempre que uma tabela muda. Quando ela está mesmo desatualizada, NOTIFY pgrst, 'reload schema'; no SQL Editor recarrega a cópia enquanto o app continua no ar.","Aum80g6NPEBr3OZVgcQeon11zKcZ9R6flOjWdewLvok",[711,717,723,729,735,741,747,753,759,765,771,778,784,790,796,802,808,814,819,824,825,831,837,843,849,855,861,867,873,879,885,891,897,903,909,915,921,927,933,939,944,950,956,962,968,974,979,985,991,997,1003,1009,1015,1021,1027,1033,1039,1045,1051,1057,1063,1069,1075,1081,1087,1093,1099,1105,1111,1117,1123,1129,1135,1141,1147,1152,1158,1164,1169,1175,1181,1187,1193,1199,1204,1210,1216,1222,1227,1233],{"path":712,"title":713,"description":714,"published":715,"category":668,"image":716,"draft":672},"\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":718,"title":719,"description":720,"published":721,"category":668,"image":722,"draft":672},"\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":724,"title":725,"description":726,"published":727,"category":668,"image":728,"draft":672},"\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":730,"title":731,"description":732,"published":733,"category":668,"image":734,"draft":672},"\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":736,"title":737,"description":738,"published":739,"category":668,"image":740,"draft":672},"\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":742,"title":743,"description":744,"published":745,"category":668,"image":746,"draft":672},"\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":748,"title":749,"description":750,"published":751,"category":668,"image":752,"draft":672},"\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":754,"title":755,"description":756,"published":757,"category":668,"image":758,"draft":672},"\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":760,"title":761,"description":762,"published":763,"category":668,"image":764,"draft":672},"\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":766,"title":767,"description":768,"published":769,"category":668,"image":770,"draft":672},"\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":772,"title":773,"description":774,"published":775,"category":776,"image":777,"draft":672},"\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":779,"title":780,"description":781,"published":782,"category":668,"image":783,"draft":672},"\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":785,"title":786,"description":787,"published":788,"category":668,"image":789,"draft":672},"\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":791,"title":792,"description":793,"published":794,"category":668,"image":795,"draft":672},"\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":797,"title":798,"description":799,"published":800,"category":668,"image":801,"draft":672},"\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":803,"title":804,"description":805,"published":806,"category":668,"image":807,"draft":672},"\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":809,"title":810,"description":811,"published":812,"category":668,"image":813,"draft":672},"\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":103,"title":815,"description":816,"published":817,"category":668,"image":818,"draft":672},"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":356,"title":820,"description":821,"published":822,"category":668,"image":823,"draft":672},"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":701,"title":5,"description":671,"published":702,"category":668,"image":689,"draft":672},{"path":826,"title":827,"description":828,"published":829,"category":668,"image":830,"draft":672},"\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":832,"title":833,"description":834,"published":835,"category":668,"image":836,"draft":672},"\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":838,"title":839,"description":840,"published":841,"category":668,"image":842,"draft":672},"\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":844,"title":845,"description":846,"published":847,"category":668,"image":848,"draft":672},"\u002Fblog\u002Fsupabase-bucket-not-found","Supabase \"Bucket not found\": as três coisas que isso significa","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.","2026-10-17","\u002Fblog\u002Fsupabase-bucket-not-found\u002Fcard-800x500.png",{"path":850,"title":851,"description":852,"published":853,"category":668,"image":854,"draft":672},"\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":856,"title":857,"description":858,"published":859,"category":668,"image":860,"draft":672},"\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":862,"title":863,"description":864,"published":865,"category":668,"image":866,"draft":672},"\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":868,"title":869,"description":870,"published":871,"category":668,"image":872,"draft":672},"\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":874,"title":875,"description":876,"published":877,"category":668,"image":878,"draft":672},"\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":880,"title":881,"description":882,"published":883,"category":668,"image":884,"draft":672},"\u002Fblog\u002Fstorage-upload-violates-row-level-security","\"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":886,"title":887,"description":888,"published":889,"category":668,"image":890,"draft":672},"\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":892,"title":893,"description":894,"published":895,"category":668,"image":896,"draft":672},"\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":898,"title":899,"description":900,"published":901,"category":668,"image":902,"draft":672},"\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":904,"title":905,"description":906,"published":907,"category":668,"image":908,"draft":672},"\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":910,"title":911,"description":912,"published":913,"category":668,"image":914,"draft":672},"\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":916,"title":917,"description":918,"published":919,"category":668,"image":920,"draft":672},"\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":922,"title":923,"description":924,"published":925,"category":668,"image":926,"draft":672},"\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":928,"title":929,"description":930,"published":931,"category":668,"image":932,"draft":672},"\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":934,"title":935,"description":936,"published":937,"category":668,"image":938,"draft":672},"\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":496,"title":940,"description":941,"published":942,"category":668,"image":943,"draft":672},"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":945,"title":946,"description":947,"published":948,"category":668,"image":949,"draft":672},"\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":951,"title":952,"description":953,"published":954,"category":668,"image":955,"draft":672},"\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":957,"title":958,"description":959,"published":960,"category":776,"image":961,"draft":672},"\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":963,"title":964,"description":965,"published":966,"category":776,"image":967,"draft":672},"\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":969,"title":970,"description":971,"published":972,"category":776,"image":973,"draft":672},"\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":975,"title":976,"description":977,"published":972,"category":668,"image":978,"draft":672},"\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":980,"title":981,"description":982,"published":983,"category":668,"image":984,"draft":672},"\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":986,"title":987,"description":988,"published":989,"category":668,"image":990,"draft":672},"\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":992,"title":993,"description":994,"published":995,"category":776,"image":996,"draft":672},"\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":998,"title":999,"description":1000,"published":1001,"category":668,"image":1002,"draft":672},"\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":1004,"title":1005,"description":1006,"published":1007,"category":668,"image":1008,"draft":672},"\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":1010,"title":1011,"description":1012,"published":1013,"category":668,"image":1014,"draft":672},"\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":1016,"title":1017,"description":1018,"published":1019,"category":668,"image":1020,"draft":672},"\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":1022,"title":1023,"description":1024,"published":1025,"category":668,"image":1026,"draft":672},"\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":1028,"title":1029,"description":1030,"published":1031,"category":668,"image":1032,"draft":672},"\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":1034,"title":1035,"description":1036,"published":1037,"category":668,"image":1038,"draft":672},"\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":1040,"title":1041,"description":1042,"published":1043,"category":668,"image":1044,"draft":672},"\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":1046,"title":1047,"description":1048,"published":1049,"category":776,"image":1050,"draft":672},"\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":1052,"title":1053,"description":1054,"published":1055,"category":776,"image":1056,"draft":672},"\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":1058,"title":1059,"description":1060,"published":1061,"category":776,"image":1062,"draft":672},"\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":1064,"title":1065,"description":1066,"published":1067,"category":668,"image":1068,"draft":672},"\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":1070,"title":1071,"description":1072,"published":1073,"category":668,"image":1074,"draft":672},"\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":1076,"title":1077,"description":1078,"published":1079,"category":668,"image":1080,"draft":672},"\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":1082,"title":1083,"description":1084,"published":1085,"category":668,"image":1086,"draft":672},"\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":1088,"title":1089,"description":1090,"published":1091,"category":668,"image":1092,"draft":672},"\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":1094,"title":1095,"description":1096,"published":1097,"category":668,"image":1098,"draft":672},"\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":1100,"title":1101,"description":1102,"published":1103,"category":668,"image":1104,"draft":672},"\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":1106,"title":1107,"description":1108,"published":1109,"category":668,"image":1110,"draft":672},"\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":1112,"title":1113,"description":1114,"published":1115,"category":668,"image":1116,"draft":672},"\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":1118,"title":1119,"description":1120,"published":1121,"category":668,"image":1122,"draft":672},"\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":1124,"title":1125,"description":1126,"published":1127,"category":776,"image":1128,"draft":672},"\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":1130,"title":1131,"description":1132,"published":1133,"category":668,"image":1134,"draft":672},"\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":1136,"title":1137,"description":1138,"published":1139,"category":776,"image":1140,"draft":672},"\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":1142,"title":1143,"description":1144,"published":1145,"category":668,"image":1146,"draft":672},"\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":398,"title":1148,"description":1149,"published":1150,"category":668,"image":1151,"draft":672},"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":1153,"title":1154,"description":1155,"published":1156,"category":668,"image":1157,"draft":672},"\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":1159,"title":1160,"description":1161,"published":1162,"category":668,"image":1163,"draft":672},"\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":373,"title":1165,"description":1166,"published":1167,"category":776,"image":1168,"draft":672},"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":1170,"title":1171,"description":1172,"published":1173,"category":776,"image":1174,"draft":672},"\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":1176,"title":1177,"description":1178,"published":1179,"category":668,"image":1180,"draft":672},"\u002Fblog\u002Fsupabase-storage-bucket-public","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":1182,"title":1183,"description":1184,"published":1185,"category":668,"image":1186,"draft":672},"\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":1188,"title":1189,"description":1190,"published":1191,"category":776,"image":1192,"draft":672},"\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":1194,"title":1195,"description":1196,"published":1197,"category":668,"image":1198,"draft":672},"\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":1200,"title":1201,"description":1202,"published":1197,"category":668,"image":1203,"draft":672},"\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":1205,"title":1206,"description":1207,"published":1208,"category":668,"image":1209,"draft":672},"\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":1211,"title":1212,"description":1213,"published":1214,"category":776,"image":1215,"draft":672},"\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":1217,"title":1218,"description":1219,"published":1220,"category":668,"image":1221,"draft":672},"\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":1223,"title":1224,"description":1225,"published":1220,"category":776,"image":1226,"draft":672},"\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":1228,"title":1229,"description":1230,"published":1231,"category":776,"image":1232,"draft":672},"\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":1234,"title":1235,"description":1236,"published":1231,"category":668,"image":1237,"draft":672},"\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",1794213649177]