[{"data":1,"prerenderedAt":467},["ShallowReactive",2],{"blog-it-new-row-violates-row-level-security-policy":3},{"id":4,"title":5,"body":6,"category":425,"cover":426,"coverAlt":427,"description":428,"draft":429,"extension":430,"faq":431,"image":447,"keywords":448,"meta":455,"navigation":456,"ogTitle":457,"path":458,"published":459,"seo":460,"stem":461,"tldr":462,"updated":459,"__hash__":466},"blog_it\u002Fblog\u002Fnew-row-violates-row-level-security-policy.md","New row violates row-level security policy su Supabase. E adesso?",{"type":7,"value":8,"toc":414},"minimark",[9,13,24,32,37,40,47,50,63,66,70,73,76,79,83,86,96,99,182,188,195,223,231,235,238,241,247,254,262,266,269,275,285,298,302,305,310,313,322,337,351,359,363,401],[10,11,12],"p",{},"Qualcosa ti ha detto di attivare Row Level Security. L'advisor dentro la tua\ndashboard Supabase, il risultato di una scansione, una checklist, qualcuno su un\nDiscord. L'hai attivato. Ora la tua app non riesce più a salvare niente. Ogni\ntentativo torna dicendo che a new row violates row-level security policy:",[14,15,20],"pre",{"className":16,"code":18,"language":19},[17],"language-text","new row violates row-level security policy for table \"profiles\"\n","text",[21,22,18],"code",{"__ignoreMap":23},"",[10,25,26,27,31],{},"Ecco la parte che guida dopo guida racconta male: ",[28,29,30],"strong",{},"la risposta che fa sparire\nquesto errore in dieci secondi disfa esattamente quello che hai appena\nattivato."," È il primo risultato che troverai, funziona subito, e lascia la\ntabella esattamente dov'era prima che qualcuno ti dicesse di sistemarla.",[33,34,36],"h2",{"id":35},"cosa-significa-new-row-violates-row-level-security-policy","Cosa significa \"new row violates row-level security policy\"",[10,38,39],{},"Al tuo database è stato chiesto di salvare una riga, ha controllato le regole di\nquella tabella, non ne ha trovata nessuna che facesse entrare proprio quella\nriga, e ha rifiutato.",[10,41,42,43,46],{},"Questo è tutto il messaggio. Niente è corrotto e niente si è perso: la riga non\nè mai stata salvata, e il resto della tabella sta esattamente come un minuto fa.\nLa formulazione arriva da Postgres, il motore di database su cui gira Supabase,\ned è per questo che suona come meccanica invece che come qualcosa scritto dal\ntuo builder. Supabase lo passa così com'è, con il suo numero accanto, ",[21,44,45],{},"42501",".",[10,48,49],{},"Quello che il messaggio non ti dirà è quale regola mancava. Una sola frase copre\ntre situazioni diverse, e dirti in quale ti trovi descriverebbe le tue regole a\nchi ha provocato l'errore:",[51,52,53,57,60],"ul",{},[54,55,56],"li",{},"La tabella ha Row Level Security attivo e nessuna regola scritta.",[54,58,59],{},"Ha una regola, e quella regola parla solo di lettura.",[54,61,62],{},"Ha una regola di scrittura, e la riga che hai mandato non la soddisfa.",[10,64,65],{},"Tutte e tre stampano quella stessa riga. La seconda è quella comune in un'app\nappena lanciata, dove una regola è stata aggiunta per rimettere in piedi gli\nschermi e del salvataggio non si è mai parlato.",[33,67,69],{"id":68},"perché-è-comparso-proprio-quando-hai-attivato-row-level-security","Perché è comparso proprio quando hai attivato Row Level Security",[10,71,72],{},"Perché attivarlo rifiuta tutto finché una regola non dice altro, e la tua stessa\napp fa parte di tutto.",[10,74,75],{},"Questa è la sequenza che quasi tutti attraversano. Attivi l'impostazione. Gli\nschermi restano vuoti, perché senza regole scritte il database ora non consegna\nrighe a nessuno, la tua app compresa. Aggiungi una regola perché le liste\ntornino, di solito la prima che suggerisce un risultato di ricerca o il tuo\nbuilder. Gli schermi si riempiono. E la prima volta che qualcuno preme salva\ncompare questo errore, su una tabella che davi per sistemata.",[10,77,78],{},"In quella sequenza non è andato storto niente. La regola che hai aggiunto\nparlava di lettura, e salvare è un'altra domanda che fino a quel momento nessuno\naveva fatto.",[33,80,82],{"id":81},"una-regola-ha-due-metà-e-solo-una-parla-di-lettura","Una regola ha due metà, e solo una parla di lettura",[10,84,85],{},"Una policy è una condizione, e dove il database applica quella condizione dipende\nda cosa gli hai chiesto.",[10,87,88,91,92,95],{},[21,89,90],{},"USING"," si applica alle righe che stanno già nella tabella. Decide quali puoi\nvedere, cambiare o togliere. ",[21,93,94],{},"WITH CHECK"," si applica alla riga che stai provando\na creare, prima che esista da qualche parte. Decide se quella riga può venire al\nmondo.",[10,97,98],{},"Quella seconda metà è la parte che sorprende, perché è una regola su qualcosa che\nnon c'è ancora.",[100,101,102,118],"table",{},[103,104,105],"thead",{},[106,107,108,112,115],"tr",{},[109,110,111],"th",{},"La tua app chiede di",[109,113,114],{},"Controllato sulle righe già nella tabella",[109,116,117],{},"Controllato sulla riga che viene scritta",[119,120,121,138,152,168],"tbody",{},[106,122,123,131,135],{},[124,125,126,127,130],"td",{},"leggere (",[21,128,129],{},"select",")",[124,132,133],{},[21,134,90],{},[124,136,137],{},"niente da controllare",[106,139,140,146,148],{},[124,141,142,143,130],{},"salvare una riga nuova (",[21,144,145],{},"insert",[124,147,137],{},[124,149,150],{},[21,151,94],{},[106,153,154,160,164],{},[124,155,156,157,130],{},"cambiare una riga (",[21,158,159],{},"update",[124,161,162],{},[21,163,90],{},[124,165,166],{},[21,167,94],{},[106,169,170,176,180],{},[124,171,172,173,130],{},"togliere una riga (",[21,174,175],{},"delete",[124,177,178],{},[21,179,90],{},[124,181,137],{},[183,184],"diagram",{"alt":185,"caption":186,"src":187},"Una stessa regola disegnata due volte. A sinistra punta a una pila di righe già dentro una tabella e due di quelle tornano indietro. A destra la stessa regola punta a una singola riga disegnata come contorno, che aspetta fuori dalla tabella, e viene respinta.","La stessa condizione, puntata su due cose diverse. In lettura le si chiede delle righe che esistono; in salvataggio, di una riga che ancora non esiste.","\u002Fblog\u002Fnew-row-violates-row-level-security-policy\u002Fusing-and-with-check-1600x780.png",[10,189,190,191,194],{},"Una policy scritta con ",[21,192,193],{},"FOR SELECT"," porta sempre e solo la prima metà, perché\nquando qualcuno legge non c'è nessuna riga nuova da controllare. Quindi non può\nmai permettere un salvataggio, per quanto permissiva sembri. È tutto qui lo\nscarto, e spiega perché le tue letture si sono riprese e le tue scritture no.",[196,197,199],"callout",{"type":198},"warn",[10,200,201,207,208,210,211,213,214,216,217,219,220,222],{},[28,202,190,203,206],{},[21,204,205],{},"FOR ALL"," si comporta diversamente, e in silenzio."," Se\nne scrivi una con una condizione ",[21,209,90],{}," e senza ",[21,212,94],{},", Postgres applica\nquella stessa condizione ",[21,215,90],{}," anche alle righe nuove. Quindi una regola\n",[21,218,205],{}," che dice che le righe appartengono al loro proprietario rifiuta un\nsalvataggio in cui il proprietario non corrisponde, senza che nessun\n",[21,221,94],{}," compaia in quello che hai scritto. Utile quando lo intendevi.\nConfuso quando stai leggendo una regola incollata da qualcun altro.",[10,224,225,226,46],{},"Se preferisci vederlo da fuori, la nostra scansione gratuita chiede al tuo\ndatabase dal vivo cosa può già leggerci uno sconosciuto, senza account e in una\nventina di secondi: ",[227,228,230],"a",{"href":229},"\u002F#scan","scansiona la tua app",[33,232,234],{"id":233},"la-soluzione-che-fa-smettere-lerrore-e-quanto-costa","La soluzione che fa smettere l'errore, e quanto costa",[10,236,237],{},"Il modo più veloce per farlo sparire è una regola che permetta qualsiasi\nscrittura da parte di chiunque, ed è per questo che è la risposta in cima quasi\novunque tu guardi.",[10,239,240],{},"Di solito arriva con questo aspetto:",[14,242,245],{"className":243,"code":244,"language":19},[17],"CREATE POLICY \"Enable insert for all users\"\n  ON public.profiles\n  FOR INSERT\n  WITH CHECK (true);\n",[21,246,244],{"__ignoreMap":23},[10,248,249,250,253],{},"Ogni riga soddisfa ",[21,251,252],{},"true",", quindi ogni salvataggio è permesso, quello della tua\napp e quello di chiunque altro abbia la chiave che viaggia dentro di essa.\nRispegnere Row Level Security fa lo stesso lavoro in modo ancora più completo.",[10,255,256,257,261],{},"Funzionano entrambe. Entrambe ti lasciano dov'eri prima che l'advisor segnalasse\nla tabella, e dopo nessuna delle due mostra alcun segno che qualcosa sia aperto,\nperché la tua app si comporta identica in tutte e quattro le combinazioni di\nimpostazione e regola. Una tabella può essere attiva, avere una policy valida,\nmostrare un badge verde nella tua dashboard e consegnare comunque le sue righe a\nuno sconosciuto. Questa è\n",[227,258,260],{"href":259},"\u002Fblog\u002Fsupabase-rls-on-but-table-still-public","l'altra metà di questo problema",",\ne vale la pena leggerla prima di incollare qualsiasi cosa.",[33,263,265],{"id":264},"la-regola-che-lascia-salvare-la-tua-app-e-solo-la-tua-app","La regola che lascia salvare la tua app, e solo la tua app",[10,267,268],{},"Nomina a chi appartiene la riga, e confrontalo con chi sta chiedendo:",[14,270,273],{"className":271,"code":272,"language":19},[17],"CREATE POLICY \"Users insert their own rows\"\n  ON public.profiles\n  FOR INSERT\n  TO authenticated\n  WITH CHECK (auth.uid() = user_id);\n",[21,274,272],{"__ignoreMap":23},[10,276,277,280,281,284],{},[21,278,279],{},"auth.uid()"," è chi è collegato e sta facendo la richiesta. ",[21,282,283],{},"user_id"," è la\ncolonna sulla riga che dice a chi appartiene. Quando quei due corrispondono, la\nriga viene salvata. Quando non corrispondono, o quando non c'è nessuno\ncollegato, viene rifiutata, e chi è stato rifiutato vede lo stesso messaggio che\nstai guardando tu.",[10,286,287,288,291,292,294,295,297],{},"Due dettagli in quella regola si guadagnano il posto. ",[21,289,290],{},"TO authenticated"," vuol\ndire che la regola vale per i visitatori collegati; toglilo e la policy vale per\ntutti, sconosciuti compresi. E la tua app deve mandare davvero la colonna\n",[21,293,283],{},", perché una regola che confronta ",[21,296,279],{}," con un valore arrivato\nvuoto non può mai corrispondere.",[33,299,301],{"id":300},"quando-la-regola-è-giusta-e-lerrore-compare-lo-stesso","Quando la regola è giusta e l'errore compare lo stesso",[10,303,304],{},"Guarda chi era collegato prima di riguardare la policy.",[183,306],{"alt":307,"caption":308,"src":309},"Tre tabelle una accanto all'altra. In ognuna una riga disegnata come contorno arriva dall'alto e la sua freccia si ferma poco prima della regola sotto. La regola della prima tabella è un contorno tratteggiato vuoto, quella della seconda porta select, quella della terza insert. Una striscia corre sotto tutte e tre portando il codice 42501.","Tre cause diverse che ti arrivano come una sola frase. Il codice 42501 è lo stesso in tutte e tre, ed è per questo che il messaggio da solo non può dirti in quale ti trovi.","\u002Fblog\u002Fnew-row-violates-row-level-security-policy\u002Fthree-causes-one-message-1600x700.png",[10,311,312],{},"Tre spiegazioni coprono quasi tutto quello che resta:",[10,314,315,318,319,321],{},[28,316,317],{},"Non c'è nessuno collegato."," ",[21,320,279],{}," torna vuoto per un visitatore che\nnon ha fatto l'accesso, quindi una regola che lo confronta con una colonna\nproprietario non può corrispondere. Questo è normale su un form di\nregistrazione, una lista d'attesa o un form di contatto, e quelli hanno bisogno\ndi una regola propria che descriva cosa può aggiungere uno sconosciuto.",[10,323,324,327,328,330,331,333,334,336],{},[28,325,326],{},"La colonna proprietario non arriva mai."," La tua regola confronta ",[21,329,279],{},"\ncon ",[21,332,283],{},", e la tua app manda tutto tranne ",[21,335,283],{},". Il confronto gira\ncontro un vuoto e fallisce ogni volta.",[10,338,339,342,343,346,347,350],{},[28,340,341],{},"La scrittura va a Storage."," I file caricati atterrano in Supabase Storage,\nche tiene le sue policy su ",[21,344,345],{},"storage.objects"," invece che sulla tua tabella. Una\nregola scritta su ",[21,348,349],{},"profiles"," non dice niente su un file.",[10,352,353,354,358],{},"C'è una quarta spiegazione, ed è quella da escludere presto: se il salvataggio\nfunziona dall'anteprima del tuo builder e fallisce dal tuo sito dal vivo, i due\nnon stanno usando la stessa chiave. Una chiave segreta ignora ogni regola che\nhai scritto, è il suo scopo, quindi un'app che salva solo finché c'è di mezzo\nuna chiave segreta è un'app le cui regole non sono mai state provate davvero.\n",[227,355,357],{"href":356},"\u002Fblog\u002Fwhich-api-keys-are-safe-in-your-frontend","Quali chiavi API sono sicure nel frontend","\nspiega come distinguere l'una dall'altra.",[33,360,362],{"id":361},"cosa-fare-oggi","Cosa fare oggi",[364,365,366],"key-takeaways",{},[51,367,368,371,377,391,394],{},[54,369,370],{},"Leggi l'errore come un rifiuto e non come un guasto. La scrittura non è avvenuta, la tabella è invariata, e non c'è niente da recuperare.",[54,372,373,374,376],{},"Controlla se la tabella ha una qualsiasi policy sulla scrittura. Una regola scritta con ",[21,375,193],{}," ha sistemato i tuoi schermi e non ha detto niente sul salvataggio.",[54,378,379,380,383,384,386,387,390],{},"Aggiungi una policy ",[21,381,382],{},"FOR INSERT"," la cui condizione ",[21,385,94],{}," nomini il proprietario della riga, e aggiungi la clausola ",[21,388,389],{},"TO"," che intendevi.",[54,392,393],{},"Conferma che la tua app manda davvero la colonna proprietario, poi riprova a salvare da collegato.",[54,395,396,397,400],{},"Lascia ",[21,398,399],{},"WITH CHECK (true)"," per le tabelle il cui contenuto ti andrebbe bene su una pagina pubblica. Per qualsiasi cosa con dentro una persona, dedicaci i due minuti.",[10,402,403,404,408,409,413],{},"Comincia dalla tabella da cui è arrivato l'errore, e controlla ogni altra\ntabella su cui hai attivato l'impostazione lo stesso pomeriggio. La\n",[227,405,407],{"href":406},"\u002Fchecklist","checklist di sicurezza da 10 minuti"," copre cos'altro tende a\nrestare aperto in un'app appena lanciata, e la\n",[227,410,412],{"href":411},"\u002Fis-your-supabase-app-safe","guida alla sicurezza di Supabase"," passa in rassegna\nil resto di quello che uno sconosciuto può raggiungere.",{"title":23,"searchDepth":415,"depth":415,"links":416},3,[417,419,420,421,422,423,424],{"id":35,"depth":418,"text":36},2,{"id":68,"depth":418,"text":69},{"id":81,"depth":418,"text":82},{"id":233,"depth":418,"text":234},{"id":264,"depth":418,"text":265},{"id":300,"depth":418,"text":301},{"id":361,"depth":418,"text":362},"Basi della sicurezza","\u002Fblog\u002Fnew-row-violates-row-level-security-policy\u002Fcover-1200x630.png","Una pila di righe dentro una tabella, con un'altra riga che aspetta fuori, disegnata solo come contorno perché non è ancora entrata.","\"New row violates row-level security policy\" significa che Supabase ha rifiutato una scrittura. La soluzione veloce riapre la tabella a chiunque.",false,"md",[432,435,438,441,444],{"q":433,"a":434},"Cosa significa \"new row violates row-level security policy\"?","Significa che al tuo database è stato chiesto di salvare una riga, ha controllato le regole di quella tabella e non ne ha trovata nessuna che facesse entrare quella riga. Quindi ha rifiutato la scrittura. Non si è perso niente e niente è rotto, perché la riga non è mai stata salvata e il resto della tabella è intatto. Il messaggio arriva da Postgres, il motore di database su cui gira Supabase, e porta il codice 42501. Quello che deliberatamente non ti dice è quale regola mancava, perché dirlo descriverebbe le tue regole a chi ha provocato l'errore.",{"q":436,"a":437},"Ho aggiunto una policy e la lettura funziona. Perché il salvataggio continua a fallire?","Perché una policy sulla lettura non dice niente sulla scrittura. Una regola porta una metà USING, che il database applica alle righe già presenti nella tabella, e una metà WITH CHECK, che applica alla riga che stai provando a creare. Una policy scritta con FOR SELECT ha sempre e solo la prima, dato che in lettura non c'è nessuna riga nuova da controllare. I tuoi schermi si riempiono di nuovo e il primo salvataggio continua a fallire. Aggiungi una seconda policy FOR INSERT con una condizione WITH CHECK.",{"q":439,"a":440},"Posso semplicemente spegnere Row Level Security per farlo sparire?","Questo fa sparire l'errore, e lascia ogni riga di quella tabella leggibile da chiunque abbia la chiave che viaggia dentro la tua app. La tua app funziona in entrambi i casi, quindi dopo niente ti dice quale delle due hai scelto. Se la tabella contiene persone, ordini o messaggi, i due minuti che costa scrivere una regola vera sono la differenza fra una tabella privata e una pubblica.",{"q":442,"a":443},"La mia policy sembra giusta e gli insert falliscono lo stesso. Cos'altro può essere?","Tre cose spiegano la maggior parte dei casi. Non c'è nessuno collegato, quindi auth.uid() torna vuoto e una regola che lo confronta con una colonna proprietario non può mai corrispondere, il che è normale su un form di registrazione o di contatto. Oppure la tua app non manda affatto la colonna proprietario, e la regola confronta contro un valore arrivato vuoto. Oppure la scrittura va in Supabase Storage invece che in una tabella, e Storage tiene le sue policy su storage.objects.",{"q":445,"a":446},"Questo errore significa che qualcuno ha provato ad attaccare la mia app?","Quasi mai. In un'app appena lanciata è quasi sempre la tua stessa app a essere rifiutata, perché Row Level Security è stato attivato prima che esistesse una regola per le tue scritture. Vale comunque la pena leggerlo invece di scartarlo: lo stesso messaggio compare quando viene rifiutata una richiesta che in quella tabella non dovrebbe scrivere, e dal messaggio da solo non puoi distinguere le due cose.","\u002Fblog\u002Fnew-row-violates-row-level-security-policy\u002Fcard-800x500.png",[449,450,451,452,453,454],"new row violates row-level security policy","supabase rls insert policy","rls blocca insert","supabase with check policy","attivare row level security supabase","errore row level security",{},true,"New row violates row-level security policy","\u002Fblog\u002Fnew-row-violates-row-level-security-policy","2026-08-27",{"title":5,"description":428},"blog\u002Fnew-row-violates-row-level-security-policy",[463,464,465],"New row violates row-level security policy significa che il tuo database ha controllato le regole di quella tabella e non ne ha trovata nessuna che permettesse la riga che stavi salvando. Ha rifiutato la scrittura e ha lasciato la tabella com'era.","Un solo messaggio copre tre situazioni diverse: nessuna regola, una regola che parla solo di lettura, o una regola di scrittura che la tua riga non soddisfa.","La risposta in cima a qualsiasi ricerca fa smettere l'errore permettendo qualsiasi scrittura da parte di chiunque. La regola che vuoi davvero costa circa due minuti in più.","uwSLGxACjNLY67j5JNW2nmiSCrvxVMrnfGEMZ0QclF4",1787826050981]