Salta ai contenuti

Codici di errore

Ogni errore restituito da un backend Rebase utilizza un unico envelope e include un code stabile. Il codice è l’elemento su cui basare la logica di branching: il messaggio è scritto per un essere umano e può essere riformulato, lo stato HTTP è condiviso da decine di problemi diversi, mentre il codice non è né l’uno né l’altro.

{
"error": {
"message": "Schema drift: table \"posts\" does not exist.",
"code": "SCHEMA_DRIFT",
"details": { "dbCode": "42P01" },
"requestId": "6f1b2f3e-8a0c-4d1b-9c3e-2a5b7c9d1e0f"
}
}
  • message — leggibile dall’uomo. Per un errore 4xx è il messaggio generato dal server; per un 5xx è volutamente generico, poiché il testo sottostante potrebbe esporre un host, un ruolo o il nome di una colonna.
  • code — uno dei valori riportati di seguito. Stabile tra versioni minori.
  • details — facoltativo e mai garantito. Consulta le regole di seguito.
  • requestId — presente ogni volta che la richiesta è passata attraverso il middleware request-ID, ovvero per ogni route sotto basePath.

Ogni richiesta sotto basePath riceve un ID: l’header X-Request-ID del chiamante quando è un UUID v4 valido, altrimenti ne viene generato uno nuovo. Viene restituito nella risposta come X-Request-ID, incluso nell’envelope di errore come requestId e associato alla riga di log del server relativa a quella richiesta.

Questa è la chiave di join. Riportala in una segnalazione di bug e un operatore potrà trovare l’unica riga di log che spiega il fallimento, contenente il motivo che non è mai stato mostrato al client.

Inviare il proprio ID è il modo in cui una traccia sopravvive a un hop: un gateway o un job runner che inoltra l’header mantiene un unico ID attraverso tutti i servizi che hanno gestito la richiesta. Un valore non valido viene ignorato anziché rifiutato — non vale la pena far fallire una richiesta a causa di un header malformato del chiamante — quindi non dare per scontato che l’ID inviato sia quello ottenuto. Leggi l’header della risposta.

details ha una funzione diagnostica, non contrattuale. È regolato da tre principi:

  1. Tutto ciò che una route imposta esplicitamente viene sempre restituito. Si tratta degli errori commessi dal chiamante descritti con precisione: quale campo di filtro era sconosciuto, quale relazione non è scrivibile, quale valore non corrispondeva al tipo.
  2. La diagnostica del database viene ridotta in produzione. Quando l’errore proviene da Postgres, details.dbCode — il valore SQLSTATE — è sempre presente: identifica la classe del problema senza rivelare nulla sui dati. dbMessage, detail e hint vengono aggiunti solo quando NODE_ENV non è production, poiché Postgres include in essi i contenuti delle righe. Il codice 23505 segnala Key (email)=(a@b.c) already exists., rispondendo di fatto alla domanda “questa persona è registrata?” per qualunque indirizzo si provi a verificare.
  3. Non basare mai il branching su details. Basalo su code. Il contenuto di details rappresenta unicamente ciò che risultava utile a una persona in quel dato punto di chiamata, ed è soggetto a modifiche.
Stato Cosa indica sulla richiesta
400 Malformata o richiedente qualcosa che non esiste nello schema. Correggi la richiesta.
401 Non autenticato, o credenziale scaduta. Effettua l’accesso o aggiorna il token.
403 Autenticato, ma non autorizzato. Riprovare con la stessa identità non servirà.
404 Route, collection o riga inesistente — oppure una riga nascosta dalle policy di row-level security.
409 Un conflitto con lo stato esistente: un duplicato o una scrittura concorrente.
413 415 422 Il corpo è troppo grande, il media type è errato o la richiesta è semanticamente rifiutata.
429 Limite di frequenza superato (rate limited). Rallenta le richieste; il messaggio indica per quanto tempo attendere.
500 L’errore è dovuto al server o al relativo database, non al chiamante. Controlla i log.
501 La route esiste, ma questo deployment non può servirla — una funzionalità disattivata o non configurata.
502 503 504 Una dipendenza era irraggiungibile, non configurata o troppo lenta.
Codice Stato Significato Cosa fare
AAL2_REQUIRED 403 La route richiede un secondo fattore e la sessione ne ha solo uno. Completa la verifica MFA, quindi riprova.
ALREADY_VERIFIED 400 L’indirizzo o il fattore è già verificato. Nessuna azione: lo stato desiderato è già attivo.
ACCOUNT_OUTRANKS_CALLER 403 L’account che si sta modificando, reimpostando o eliminando possiede un ruolo o uno scope che il chiamante non possiede. details.beyond li nomina. Fai eseguire la modifica a qualcuno che li possiede.
ANONYMOUS_AUTH_DISABLED 403 L’accesso anonimo è disabilitato su questo server. Abilitalo, oppure accedi con un’identità reale.
API_KEY_SELF_MANAGEMENT_FORBIDDEN 403 Una chiave API ha tentato di elencare, creare, modificare o revocare chiavi API, del proprio tipo o personali. Gestisci le chiavi come persona che possiede keys:write, oppure con la service key.
AUTH_MIDDLEWARE_MISSING 500 Una route protetta è stata eseguita senza il middleware di autenticazione di Rebase a monte, quindi la credenziale del chiamante non è mai stata esaminata. Esegui il mount dell’app tramite il router delle funzioni anziché direttamente sul tuo server.
BOOTSTRAP_ANONYMOUS 403 Il bootstrap del primo amministratore è stato tentato da un chiamante anonimo. Prima effettua l’accesso.
BOOTSTRAP_COMPLETED 403 Il primo amministratore esiste già. Chiedi a un amministratore esistente di assegnare il ruolo.
BOOTSTRAP_NOT_FIRST_USER 403 Il bootstrap è riservato esclusivamente al primo utente in assoluto, e questo non lo è. Chiedi a un amministratore esistente di assegnare il ruolo.
CAPTCHA_FAILED 400 Il provider ha rifiutato il token CAPTCHA. Risolvi una nuova verifica CAPTCHA.
CAPTCHA_REQUIRED 400 La route richiede un token CAPTCHA e non ne è stato inviato alcuno. Includi il token.
CHALLENGE_EXHAUSTED 401 Troppi codici errati inseriti per una singola verifica MFA. Avvia una nuova verifica.
EMAIL_EXISTS 409 Esiste già un account con quell’indirizzo — alla registrazione, su un cambio di indirizzo, e seguendo un link di cambio indirizzo quando un altro account ha preso l’indirizzo mentre era in attesa. Accedi o avvia il recupero della password; per un cambio di indirizzo, scegline un altro.
EMAIL_NOT_CONFIGURED 503 Sono stati richiesti magic link o OTP e il server non dispone di un mail transport. Configura SMTP o utilizza un altro metodo di accesso.
EMAIL_NOT_VERIFIED 403 L’account esiste ma il relativo indirizzo non è verificato. Verifica l’indirizzo.
FACTOR_NOT_VERIFIED 400 Il fattore MFA è stato registrato ma non è mai stato confermato. Conferma il fattore.
IDENTITY_ALREADY_LINKED 409 Quell’identità OAuth appartiene a un altro account. Accedi con essa, oppure scollecala prima da quell’account.
IMPERSONATION_FORBIDDEN 403 Una richiesta ha inviato x-rebase-impersonate e il chiamante non può eseguire una richiesta come un altro utente. Può farlo solo la sessione di un amministratore che ha effettuato l’accesso, mai una chiave API né la chiave di servizio. Inviala con la sessione di un amministratore, oppure togli l’header.
IMPERSONATION_INVALID 400 x-rebase-impersonate è stato inviato vuoto. Invia l’uid dell’utente per conto del quale agire, oppure togli l’header.
IMPERSONATION_TARGET_NOT_FOUND 404 x-rebase-impersonate non indica nessun utente attivo: nessun account ha quell’uid, oppure è disattivato. Controlla l’uid.
IMPERSONATION_UNAVAILABLE 501 L’autenticazione di questo backend non può eseguire una richiesta come un altro utente, perché il suo AuthAdapter non ha resolveUser. Implementa resolveUser nell’adapter, oppure togli l’header.
IMPERSONATION_UNSUPPORTED 400 x-rebase-impersonate è stato inviato a una route che non può essere eseguita come un altro utente. Lo rispettano solo l’API dati e le funzioni personalizzate, e il socket realtime rispetta impersonate in AUTHENTICATE. Invia la richiesta senza l’header.
INVALID_ACCOUNT 400 L’account si trova in uno stato su cui questa operazione non può agire. Consulta il messaggio.
INVALID_CHALLENGE 400 La verifica MFA è sconosciuta o scaduta. Avviane una nuova.
INVALID_CODE 400 / 401 Il codice OTP o MFA non è corretto: 400 dall’accesso con codice email (/auth/otp/verify), 401 da una registrazione o da un challenge MFA. Riprova con il codice attuale.
INVALID_CREDENTIALS 401 Email o password errata — deliberatamente senza specificare quale delle due. Riprova, o reimposta la password.
INVALID_PLATFORM_TOKEN 401 Un token di piattaforma rpt_ è stato rifiutato: firma errata, audience sbagliata, scaduto o una durata oltre il limite. Il messaggio dice quale. Fai emettere un token nuovo alla piattaforma: su Rebase Cloud, esegui di nuovo il comando.
INVALID_SCOPES 400 A una chiave è stato richiesto qualcosa che non è uno scope: malformato, sconosciuto, o con un target che lo scope non accetta. details.problems indica quali e perché; details.validScopes elenca gli scope che una chiave può avere. Da 0.25 Omette keys:read e keys:write, che nessuna chiave può avere; su 0.24 li elenca. Usa un nome dell’elenco. Vedi Ruoli e scope.
INVALID_TOKEN 400 / 401 Un token di verifica, reimpostazione, magic link o cambio indirizzo è malformato, sconosciuto, consumato o scaduto (400). Una credenziale di un provider OAuth o un refresh token che non si verifica restituisce 401. Richiedi un nuovo link, o accedi di nuovo.
KEY_MANAGEMENT_SCOPE 400 A una chiave sono stati richiesti keys:read o keys:write. Nessuna chiave può gestire le chiavi. details.scopes li nomina. Escludili.
LAST_ADMIN 403 La modifica lascerebbe il progetto senza alcun amministratore. Promuovi prima qualcun altro.
MFA_REQUIRED 401 La password era corretta e l’account ha un secondo fattore verificato, quindi l’accesso è completato solo a metà. details contiene un token temporaneo limitato alla verifica MFA — non è una sessione. Apri una verifica e rispondi; la risposta alla verifica rilascia la sessione.
NO_SESSION 401 Non è stato fornito alcun cookie di sessione o refresh token. Normale al primo caricamento della pagina. Accedi.
NOT_ANONYMOUS 400 Una route di passaggio da account anonimo è stata chiamata da un account reale. Nulla da aggiornare.
OAUTH_ERROR 401 Il provider OAuth ha rifiutato la richiesta o ha restituito un errore. Riprova il flusso; il messaggio riporta la motivazione del provider.
PERSONAL_KEYS_DISABLED 403 Le chiavi API personali sono disattivate su questo backend. Imposta personalKeys: true nel blocco auth della collezione users.
PERSONAL_KEY_NEEDS_ACCOUNT 403 La service key o una sessione ospite ha tentato di usare le route delle chiavi personali. Nessuna delle due ha un account con cui una chiave possa agire. Accedi a un account, oppure crea una chiave di servizio sotto /api/admin/api-keys.
PLATFORM_TOKENS_OFF 401 Un token di piattaforma rpt_ ha raggiunto un server che non li accetta: REBASE_PLATFORM_TOKEN_KEY e REBASE_PLATFORM_TOKEN_AUDIENCE non sono impostate. La piattaforma che ospita l’app le imposta entrambe al deploy; esegui di nuovo il deploy, o accedi all’app in un altro modo.
RATE_LIMITED 429 Troppi tentativi da parte di questo chiamante. Rallenta le richieste; il messaggio indica per quanto tempo attendere.
REDIRECT_URI_NOT_ALLOWED 400 La destinazione del reindirizzamento non è presente nella lista dei consentiti (allow-list). Aggiungila alla configurazione del provider.
REGISTRATION_DISABLED 403 L’auto-registrazione è disabilitata. Chiedi a un amministratore di creare l’account.
ROLE_EXCEEDS_CALLER 403 I ruoli che si stanno concedendo possiedono uno scope, o admin, che il chiamante non possiede. details.beyond li nomina. Fai concedere il ruolo a qualcuno che li possiede.
ROLE_EXCEEDS_CREATOR 403 A una chiave di servizio è stato dato un ruolo RLS che il suo creatore non possiede. Solo un admin può dare qualsiasi ruolo. details.roles li nomina. Rimuovi il ruolo, oppure fai creare la chiave a un admin.
ROLE_EXISTS 409 Questo nome di ruolo è già occupato. Scegli un altro nome.
ROLE_LOOKUP_FAILED 503 Impossibile leggere i ruoli del chiamante — su una route di amministrazione, o su una richiesta di dati in un backend con config.auth. Si blocca per sicurezza invece di fidarsi dei ruoli nel token. Un token il cui uid non corrisponde ad alcun account, compreso un uid che la tabella degli utenti non può contenere, è un 401, non questo (Da 0.25; su 0.24 un uid che la tabella non può contenere è questo 503). Un database non raggiungibile è DATABASE_UNAVAILABLE, non questo (Da 0.25; su 0.24 è questo 503). Riprova; controlla il database.
SCOPE_EXCEEDS_CREATOR 403 A una chiave è stato richiesto uno scope che il suo creatore non possiede. Una chiave non possiede mai più dell’account che la crea. details.scopes li nomina. Rimuovili, oppure fai creare la chiave a qualcuno che li possiede.
SCOPE_MISSING 403 La credenziale non possiede lo scope richiesto da questa route, collezione, sorgente di storage o funzione. details.requiredScope lo nomina, target incluso. Per una persona, un ruolo che dichiara lo scope. Per una chiave, una chiave che lo possiede. Vedi Ruoli e scope.
SCOPE_NOT_DECLARED 500 Da 0.25 Una route protetta con requireScope nomina uno scope dell’app che questo backend non dichiara, quindi nessuno lo possiede, nemmeno un amministratore. Un nome che non è affatto uno scope, o uno scope integrato scritto male come data:raed, non arriva mai fin qui: requireScope lancia un errore nel punto in cui la route viene registrata. Su 0.24 in entrambi i casi ogni chiamante riceve 403 SCOPE_MISSING. Dichiara lo scope sotto auth.scopes nella collezione degli utenti, oppure correggi il nome. Vedi Ruoli e scope.
SELF_DELETE 400 Un amministratore ha tentato di eliminare il proprio account. Fai eseguire l’operazione a un altro amministratore.
SESSION_REVOKED 401 È stato eseguito il logout dalla sessione altrove, oppure tutte le sessioni sono state revocate, oppure l’account è stato eliminato. Ogni accesso che accetta una sessione lo risponde a un access token di questo tipo: l’API dei dati, lo storage, le funzioni personalizzate e le route di amministrazione (Da 0.25; su 0.24 i primi tre rispondono UNAUTHORIZED “Invalid or expired token”). L’SDK esegue il refresh, il refresh viene rifiutato, e l’SDK esegue il logout. Accedi nuovamente.
ACCOUNT_DISABLED 401/403 Un amministratore ha disattivato l’account: l’accesso (403), il refresh e ogni token che possiede (401) vengono rifiutati, a ogni accesso che accetta una sessione (Da 0.25; su 0.24 l’API dei dati, lo storage e le funzioni personalizzate rispondono UNAUTHORIZED). Chiedi a un amministratore.
EMAIL_NOT_CONFIRMED 403 requireEmailVerification è attivo e l’indirizzo non è ancora verificato. Risposto solo per una password corretta; viene inviato un nuovo link via email. Segui il link nell’email.
PROOF_REQUIRED 409 POST /auth/verify-email: l’account possiede una password o un’identità che nessuno ha dimostrato, e la richiesta non dimostra nessuna delle due. Il token non è consumato. Invia password per mantenerla, oppure removeUnproven: true per verificare senza di essa.
UNDELIVERABLE_ADDRESS 400 / 409 È stata richiesta un’email di verifica per un indirizzo che l’email non può raggiungere — quello di un guest, o un segnaposto di X (400) — oppure un account ha richiesto di spostarsi su un simile indirizzo (409, POST /auth/change-email). Imposta prima un indirizzo reale.
EMAIL_UNCHANGED 400 POST /auth/change-email ha nominato l’indirizzo attuale dell’account. Nulla da cambiare.
ANONYMOUS_USER 403 Un guest ha richiesto di cambiare il proprio indirizzo email; un guest non ne possiede uno proprio. Trasformalo prima in un account (POST /auth/anonymous/link).
MFA_NOT_ENROLLED 400 Sono stati richiesti codici di recupero per un account senza alcun secondo fattore verificato. Registra prima un fattore.
HOOK_REJECTED 400 Un hook beforeUserCreate, beforeLogin, beforeUserDelete o beforeEmailChange ha lanciato un’eccezione. Il messaggio è quello dell’hook; un hook che ha scelto uno status 4xx risponde con esso. Leggi il messaggio.
INVALID_JSON 400 Il corpo della richiesta non è JSON. Invia un corpo JSON.
SELF_DISABLE 400 Un amministratore ha tentato di disattivare il proprio account. Chiedi a un altro amministratore.
NOT_SUPPORTED 501 Il repository di autenticazione di questo backend non può fare ciò che è stato richiesto (disattivare account, cambiare un indirizzo). Riavvia il server affinché la colonna venga aggiunta, oppure usa un repository che lo supporta.
UNKNOWN_SCOPE_TARGET 400 Il target di uno scope nomina una collezione, una sorgente di storage o una funzione che questo backend non serve. details elenca quelli che serve. Correggi il target.
UNVERIFIED_IDENTITIES 409 Un magic link, un codice via email o un ripristino della password ha dimostrato l’indirizzo di un account non verificato, e l’account ha un’identità di accesso il cui provider non ha mai verificato quell’indirizzo. Il repository di autenticazione non può rimuoverla (non ha unlinkUserIdentity), quindi la prova viene rifiutata invece di lasciare quella via d’accesso su un account verificato. Implementa unlinkUserIdentity nel repository di autenticazione personalizzato, o fai verificare l’account da un amministratore.
SETUP_REQUIRED 403 Il progetto non ha ancora un amministratore, quindi questa route non è disponibile. Completa la configurazione del primo amministratore.
TOKEN_ALREADY_USED 401 È stato riutilizzato un token monouso, oppure un refresh token che è stato ruotato più di refreshTokenReuseIntervalSeconds fa. Richiedine uno nuovo, oppure accedi di nuovo.
TOKEN_EXPIRED 401 Il token ha superato la sua durata di validità. Richiedine uno nuovo.
USER_NOT_FOUND 404 Nessun account trovato con questo id. Controlla l’id.
WEAK_PASSWORD 400 La password non rispetta la policy delle password (per impostazione predefinita almeno 8 caratteri con una lettera maiuscola, una minuscola e una cifra) — in fase di registrazione, di reimpostazione o modifica, e per la password scelta da un amministratore: POST /api/admin/users, una creazione sulla collection degli utenti tramite la data API, PUT /api/admin/users/:id o POST /api/admin/users/:id/reset-password. Scegline una più robusta. Un amministratore che importa account può inviare skipPasswordPolicy: true in una creazione.
Codice Stato Significato Cosa fare
AGGREGATE_NOT_SUPPORTED 501 Questo driver non è in grado di calcolare l’aggregazione richiesta. Usa un driver che la supporti, o calcolala nel client.
BRANCHING_UNSUPPORTED — È stato richiesto un branch del database tramite il websocket di Studio sul database di sviluppo gestito (PGlite), in cui un branch coincide con il genitore e nulla verrebbe isolato. Il rifiuto è lo stesso mostrato da rebase db branch. Punta DATABASE_URL verso un’istanza Postgres dedicata (rebase dev --docker ne avvia una) ed esegui lì il branch.
BATCH_TOO_LARGE 400 POST /api/data/_batch contiene più operazioni del limite consentito per batch (1000 per impostazione predefinita). Un batch costituisce una singola transazione e mantiene i lock per l’intera durata. Invialo a blocchi; il messaggio indica il limite e il numero di operazioni inviate.
BATCH_UNSUPPORTED 400 Il driver di questo backend non può eseguire scritture tra più collection in modo atomico, e un ciclo di scritture singole non sarebbe né atomico né un singolo round trip. Invia le scritture come richieste separate, oppure come chiamate /bulk per ciascuna collection.
BULK_TOO_LARGE 400 Il corpo della richiesta bulk supera il limite di elementi configurato. Suddividi la richiesta.
BULK_UNSUPPORTED 400 Questa collection o questo driver non supporta scritture in blocco (bulk). Scrivi le righe una alla volta.
CALLBACK_REJECTED 400 Un callback di collection ha rifiutato la scrittura. Un’istruzione throw proveniente da beforeSave/beforeDelete/after* produce un 400 contenente il messaggio personalizzato dell’autore; un beforeDelete che restituisce false produce un 403. details.stage specifica quale callback, details.path la collection. Leggi il messaggio — è stato scritto da questo progetto, non da Rebase.
CALLBACK_RECURSION 500 Scritture avviate da hook annidate per più di 16 livelli: la scrittura context.data di un hook esegue di nuovo gli hook di quella collection, e nulla nella catena la interrompe — di solito un afterSave che aggiorna la propria riga senza condizioni. L’intera scrittura è stata annullata. Il messaggio nomina l’hook e la collection; details.chain elenca ogni passaggio hook → scrittura. Rendi condizionale la scrittura dell’hook: agisci solo su status === "new", oppure saltala quando values già contiene ciò che scriverebbe.
CURSOR_WITH_OFFSET 400 ?after= è stato combinato con ?offset= o ?page=. Un cursore stabilisce già l’inizio della pagina, quindi applicarvi un offset salta silenziosamente quel numero di righe oltre il cursore — un divario invisibile al chiamante nella risposta. Usa l’uno o l’altro.
DISTINCT_NOT_APPLICABLE 400 ?distinct=true è stato combinato con una query di ricerca o vettoriale. Entrambe assegnano un punteggio a ciascuna riga, quindi due righe non risulteranno mai identiche e DISTINCT non raggrupperebbe nulla — sembrerebbe funzionare ma non modificherebbe nulla. Rimuovi uno dei due parametri.
DISTINCT_ORDER_BY_NOT_SELECTED 400 Una lettura con distinct è ordinata in base a una colonna che non restituisce. Una query SELECT DISTINCT può essere ordinata solo in base alle colonne presenti nel proprio elenco select, altrimenti le righe raggruppate non avrebbero un ordine definito. details.fields ne specifica i nomi. Aggiungi tali campi a ?fields=, oppure rimuovili da ?orderBy=.
DATABASE_UNAVAILABLE 503 Da 0.25 Impossibile raggiungere il database: la connessione è stata rifiutata o interrotta, l’host non si è risolto, oppure il server si sta arrestando o avviando. Rispondono tutti gli accessi, compresi l’autenticazione, le route di amministrazione e il socket realtime (un frame ERROR). Inviato con Retry-After: 5. Su 0.24 la stessa interruzione risponde ROLE_LOOKUP_FAILED, INTERNAL_ERROR o un 500 con il codice ECONNREFUSED. Riprova; l’SDK lo fa. Controlla che il database sia in esecuzione e raggiungibile dal server.
DB_CONNECT_TIMEOUT 503 L’apertura di una nuova connessione al database ha richiesto più tempo di DB_POOL_CONNECT_TIMEOUT: il database è lento ad accettare connessioni, oppure è lontano. Inviato con Retry-After. Riprova; l’SDK lo fa. Controlla il carico del database e la rete verso di esso.
DB_PERMISSION_DENIED 500 Postgres ha rifiutato l’istruzione (42501): una policy di row-level security che nega l’accesso a questo ruolo o un comando GRANT mancante. Consulta Risoluzione dei problemi.
DB_POOL_EXHAUSTED 503 Ogni connessione del pool è rimasta occupata per DB_POOL_CONNECT_TIMEOUT, quindi questa richiesta non ha mai raggiunto il database. Carico, non un guasto; inviato con Retry-After. Il server registra il rimedio nei log una volta al minuto. Riprova; l’SDK lo fa. Aumenta DB_POOL_MAX, oppure individua le query lente o le transazioni lunghe che occupano le connessioni.
FIELD_NOT_READABLE 400 Un filtro, orderBy, fields, la select di un aggregato o groupBy specifica un campo che i ruoli di questo chiamante non possono leggere (access.read), un percorso annidato o un ordinamento di aggregato specifica una relazione che non possono leggere — oppure un’operazione sul campo ($inc, $push, …) ne ha come destinazione uno, caso in cui un limite rifiutato rivelerebbe il valore memorizzato. Un campo che nessuna risposta può contenere non deve poter essere interrogato da alcuna query, altrimenti il valore sarebbe ricavabile un predicato alla volta. Un filtro attraverso una relazione (author.salary) e un ordinamento di aggregato sul campo di una relazione (max(staff.salary)) sono valutati secondo la regola della destinazione. details.violations elenca ciascun campo. Un campo nascosto con excludeFromApi risponde come se non esistesse: un filtro, orderBy, fields, include, la select di un aggregato o groupBy, oppure vector_search che lo specifica ottiene esattamente la risposta di un nome scritto male (UNKNOWN_FILTER_FIELD, UNKNOWN_ORDER_BY_FIELD, UNKNOWN_FIELD, UNKNOWN_RELATION, UNKNOWN_AGGREGATE_FIELD o UNKNOWN_VECTOR_PROPERTY), e nessuna risposta di campo sconosciuto ne elenca uno. Rimuovi il campo dalla query, oppure acquisisci il ruolo necessario. Consulta Accesso ai campi.
FIELD_NOT_WRITABLE 400 Il corpo imposta un campo che i ruoli di questo chiamante non possono scrivere (access.write). Viene rifiutato anziché ignorato: una scrittura che tralasciasse un campo segnalerebbe un successo per una modifica mai avvenuta. Lo stesso codice rifiuta una scrittura tramite un genitore che imposta una relazione che il chiamante non può scrivere, e un aggiornamento che imposta un campo softDelete a un valore — solo un’eliminazione lo marca. details.violations elenca ciascun campo. Rimuovi il campo, oppure acquisisci il ruolo necessario. Un campo che nessuno può scrivere restituisce invece VALIDATION_EXCLUDED_FIELDS.
HISTORY_UNAVAILABLE 503 Una scrittura su una collection con history: true è stata rifiutata perché non è stato possibile registrarne la voce di cronologia: il database non ha la tabella rebase.entity_history oppure, per openRebase e rebase console, la funzione rebase.record_history. Nessun backend con la cronologia attiva si è mai avviato su questo database. Non è stato eseguito nulla, callback comprese, e le letture non ne risentono. Sollevato da openRebase e restituito da un backend creato con provision: false. Avvia il backend una volta con la cronologia attiva e provision: true (rebase dev lo fa), poi riprova.
IDEMPOTENCY_KEY_IN_PROGRESS 409 Una richiesta precedente con la stessa Idempotency-Key è ancora in esecuzione. Riprova al termine dell’operazione.
IDEMPOTENCY_KEY_REUSED 422 La stessa Idempotency-Key è arrivata con un corpo differente. Usa una nuova chiave, oppure invia il corpo originale.
INVALID_AGGREGATE_FUNCTION 400 ?select= ha indicato una funzione diversa da count, sum, avg, min o max. Usane una tra queste; il messaggio ne riporta l’elenco.
INVALID_AGGREGATE_SELECT 400 Una voce di ?select= non rispetta il formato fn(field), oppure a una funzione diversa da count() non è stato associato alcun campo. Utilizza la sintassi sum(total), count(), avg(score).
INVALID_AGGREGATE_WINDOW 400 offset, page o orderBy su un’aggregazione senza groupBy, o un cursore su qualsiasi aggregazione. Un’aggregazione non raggruppata è una riga, e un gruppo non è una riga dopo cui un cursore possa proseguire. Aggiungi groupBy, o toglili; pagina i gruppi con offset o page. Vedi Aggregazioni.
INVALID_BATCH_BODY 400 Un’operazione in /_batch è priva di op, collection, values o id, specifica una collection non gestita da questo backend, oppure riutilizza un nome ref. Consulta il messaggio; indica l’operazione in base all’indice.
INVALID_BATCH_REF 400 Un { "$ref": "<name>.<field>" } non fa riferimento ad alcuna operazione precedente, punta in avanti o richiede un campo non presente nella riga referenziata. Si possono risolvere solo riferimenti all’indietro. Definisci l’operazione con ref prima di referenziarla.
INVALID_BULK_BODY 400 Il corpo della richiesta bulk non presenta il formato atteso. Invia l’array items documentato.
INVALID_CONFLICT_TARGET 400 Il parametro on_conflict / onConflict di un upsert indica colonne senza garanzia di unicità, le specifica senza upsert: true, oppure è inviato su una creazione annidata, dove una riga trovata passerebbe sotto il nuovo parent. In caso contrario, Postgres restituirebbe l’errore 42P10 dall’interno di una transazione che ha già svolto del lavoro. Anche qualsiasi upsert sulla collection degli utenti (auth), dove una creazione e un aggiornamento seguono regole diverse. Dichiara validation: { unique: true } o un indice unique; il messaggio elenca i target effettivamente disponibili. Sulla collection degli utenti, invia un POST per creare e un PATCH per aggiornare.
INVALID_COUNT 400 ?count= non è exact né none. Rifiutato anziché letto come valore predefinito: un ?count=nnone scritto male pagherebbe il conteggio che doveva saltare. Invia exact (il valore predefinito) oppure none. Vedi Saltare il conteggio.
INVALID_CURSOR 400 Il cursore after non è leggibile, o indica un id di riga che non corrisponde alle colonne chiave della collection: è stato troncato, ricodificato o costruito a mano. Restituisci invariato il meta.nextCursor della pagina precedente. Vedi Paginazione.
INVALID_DELETED_PARAM 400 ?deleted= non è né include né only. Viene rifiutato anziché ignorato: un errore di battitura come ?deleted=true che nascondesse silenziosamente tutte le righe eliminate sembrerebbe aver funzionato, rispondendo in realtà alla domanda opposta. Invia include (attive ed eliminate) o only (solo eliminate). Omettilo per ottenere solo le righe attive.
INVALID_DISTINCT 400 ?distinct= non è true o false. Invia uno di questi valori; sono accettati anche 1 e 0.
INVALID_FIELD_OPERATION 400 È stato utilizzato un operatore $inc / $push / $pull / $merge su un tipo di proprietà non compatibile, con un operando dal formato non corretto, con due operatori sullo stesso campo, digitato in modo errato, o in un’operazione di creazione — dove non esiste un valore salvato su cui operare. Consulta Scrittura via REST; il messaggio indica il campo interessato.
INVALID_FILTER_FIELD 400 Il filtro indica una proprietà non presente in questa collection. Verifica la correttezza del nome rispetto alla collection.
INVALID_FILTER_OPERATOR 400 L’operatore non è supportato da questo tipo di proprietà — per esempio like su un numero o una data. Consulta Interrogare i dati.
INVALID_FILTER_VALUE 400 Il valore di un filtro non può essere interpretato come il tipo della colonna a cui è confrontato: ?id=eq.abc su una chiave intera, un’etichetta non presente nell’enum, un timestamp non valido, un numero che supera l’intervallo consentito dal tipo. details.dbCode riporta il codice SQLSTATE. Invia un valore corrispondente al tipo della colonna.
INVALID_HARD_PARAM 400 ?hard= non è true o false. Qualsiasi altro valore viene rifiutato anziché interpretato come “no” — un errore di battitura che applica un soft-delete quando il chiamante aveva richiesto una rimozione permanente indurrebbe a credere che i dati siano stati eliminati definitivamente. Invia true o false.
INVALID_INCLUDE 400 ?include= è malformato: non è un elenco di percorsi valido, oppure supera il livello massimo di annidamento consentito. L’errore viene intercettato al limite della richiesta anziché propagarsi dal driver come errore 500. Consulta il messaggio; indica il percorso non valido.
INVALID_INPUT 400 Il corpo della richiesta non ha superato la convalida. Consulta il messaggio.
INVALID_LIMIT — Una sottoscrizione realtime ha richiesto un limite al di fuori dell’intervallo consentito. Restituito come frame ERROR di WebSocket, non come risposta HTTP. Riduci il limite.
INVALID_LOGICAL_GROUP 400 Un gruppo ?or= / ?and= è malformato o supera il livello di annidamento consentito. Consulta il messaggio; mostra la regola di appiattimento.
INVALID_OFFSET 400 ?offset= non è un numero intero maggiore o uguale a 0. Invia un numero intero non negativo.
INVALID_ORDER_BY 400 ?orderBy= non è field, field:desc o un array JSON di { field, direction }. Consulta il messaggio; mostra tutte e tre le sintassi valide.
INVALID_PAGE 400 ?page= non è un numero intero maggiore o uguale a 1. La numerazione delle pagine parte da 1, quindi ?page=0 è considerato un errore e non la prima pagina. Invia 1 o un valore superiore, oppure usa ?offset=.
INVALID_PARAM 400 Un parametro di query è malformato. Consulta il messaggio.
INVALID_QUERY_BODY 400 Da 0.25 Il body di un POST …/query contiene un valore che l’URL non avrebbe potuto portare: una lista per un parametro che l’URL legge una volta sola (fields, limit, …), un oggetto per un filtro, oppure un parametro presente anche nell’URL. Scrivi ogni valore come lo scrive l’URL — una stringa, o una lista per un filtro ripetuto; where, include, orderBy e vector accettano JSON. Vedi Query troppo lunghe per un URL.
INVALID_VECTOR 400 ?vector= non è un array JSON di numeri. Invia [0.1,0.2,0.3].
INVALID_VECTOR_DISTANCE 400 ?vector_distance= non è cosine, l2 o inner_product. Utilizza uno di questi tre valori.
INVALID_VECTOR_THRESHOLD 400 ?vector_threshold= non è un numero. Invia un numero.
INVALID_WHERE 400 ?where= non è un oggetto JSON che mappa campi a condizioni. Invia {"status":["==","active"]}.
KEY_IMMUTABLE 400 Un update nomina la chiave della riga con un valore diverso da quello con cui è indirizzata — nel corpo, oppure scritto da un beforeSave. Una riga non può spostarsi su un’altra chiave: tutto ciò che segue la scrittura (la rilettura, afterSave, la storia, il realtime) la indirizza con la chiave che aveva. Rifiutato prima che venga eseguito qualsiasi hook, senza che nulla venga scritto, su ogni canale. details.violations nomina il campo. Crea la riga con la nuova chiave ed elimina questa. Inviare la chiave che la riga già possiede va bene.
MISSING_AGGREGATE_SELECT 400 La route di aggregazione è stata chiamata senza ?select=. Aggiungine uno, ad es. ?select=count().
NO_COLLECTIONS 404 Il progetto non gestisce alcuna collection: nessuna dichiarata nel codice e nessuna tabella da cui ricavarle. Da 0.25 Quando esistono tabelle ma la row-level security è disattivata su di esse, il messaggio le nomina, con l’SQL per attivarla, e details.unprotectedTables le elenca; su 0.24 dice che non ci sono tabelle. Crea delle tabelle — tramite migrazione, SQL o un file collection seguito da rebase db push — e riavvia.
NOT_FOUND 404 Nessuna riga con questo id in questa collection — oppure una riga nascosta a questo chiamante dalla row-level security. Controlla l’id, poi le securityRules della collection.
UNKNOWN_RELATION 400 / 404 ?include= indica un elemento che non costituisce una relazione nella collection. Lo stesso codice risponde con 404 quando è invece un percorso URL annidato a indicarne una inesistente, ad esempio /api/data/authors/1/posts dove authors non ne dichiara alcuna — in quel caso l’URL non fa riferimento a nulla, quindi si tratta di una risorsa non trovata anziché di una richiesta malformata. Controlla il nome della relazione — il messaggio elenca quelle presenti nella collection. Un riferimento inverso deve essere dichiarato sul genitore per essere esplorabile.
ORDER_BY_FIELD_NOT_SORTABLE 400 L’ordinamento fa riferimento a una proprietà non ordinabile. Ordina in base a una proprietà supportata da colonna.
PAGE_WITH_OFFSET 400 ?page= è stato combinato con ?offset= — oppure page con offset in una find(), che l’SDK client, il rebase.data in-process e il client offline rifiutano con lo stesso codice prima di qualsiasi richiesta. Descrivono la stessa finestra, e page prevaleva in silenzio su un offset che il chiamante non vedeva mai applicato. Invia uno solo dei due.
PAYLOAD_TOO_LARGE 413 Il corpo della richiesta supera il limite configurato. Invia meno dati, oppure aumenta il limite.
READ_ONLY_TRANSACTION 409 Un callback afterRead ha tentato di eseguire una scrittura. Una lettura con ambito richiesta viene eseguita all’interno di una transazione READ ONLY, pertanto né il callback né le funzioni da esso chiamate possono eseguire scritture. Sposta la scrittura all’esterno dell’operazione di lettura: usa un background job, oppure rebase.dataAsAdmin da un cron job o da una custom function.
RELATION_HAS_NO_PIVOT 400 La scrittura includeva un payload di collegamento, ma il percorso non raggiunge la destinazione tramite una relazione manyToMany che dichiara through.properties — di conseguenza non è presente alcuna riga di giunzione su cui inserirlo. Dichiara through.properties nella relazione, oppure rimuovi il payload dalla scrittura. Consulta Relazioni.
RELATION_MISCONFIGURED 500 Una relazione non corrisponde allo schema registrato. L’operazione viene rifiutata anziché ignorata: tralasciarla riporterebbe il successo di una scrittura mai avvenuta, oppure l’assenza di righe in realtà esistenti. Esegui rebase schema generate se lo schema generato è meno recente del database.
RELATION_NOT_UNLINKABLE 400 La relazione non può essere scollegata da questo lato. Esegui la scrittura dal lato proprietario della relazione.
RELATION_NOT_WRITABLE 400 Il percorso annidato non è una relazione scrivibile. Consulta Relazioni.
RELATION_PIVOT_UNSUPPORTED 400 La relazione dichiara colonne di giunzione, ma questa sorgente dati non supporta la loro scrittura. Il collegamento in sé funziona comunque; solo il payload associato non è supportato. Verifica le capacità del driver.
RELATION_SOURCE_KEY_EMPTY 400 Una scrittura di relazione non disponeva della chiave di origine a cui agganciare il collegamento. Salva prima la riga genitore.
RESULT_TOO_LARGE — Da 0.25 Un’istruzione inviata tramite EXECUTE_SQL del socket realtime — admin.executeSql da un client, le letture del catalogo del pannello admin — ha restituito più di 128 MB di righe, quindi non ne è stata inviata nessuna. Consegnato come frame WebSocket ERROR. Le esecuzioni della console SQL stessa non vengono rifiutate: mostrano le prime righe. Aggiungi un LIMIT, o seleziona meno colonne, e leggi il risultato a parti.
ROW_IN_TRASH 409 La chiave di un upsert appartiene a una riga nel cestino (una riga eliminata con soft delete mantiene comunque la sua chiave). Un upsert non scrive in una riga eliminata, su nessun canale: ?on_conflict= su REST, gli upsert di /bulk e /_batch, l’SDK e il socket realtime. Non è stato scritto nulla. Ripristina prima la riga (un update che imposta il campo di soft-delete a null), oppure elimina definitivamente con ?hard=true e ripeti l’upsert. Vedi Soft delete.
SCHEMA_DRIFT 500 Una tabella o una colonna prevista dal codice non esiste nel database. Esegui rebase db push in ambiente di sviluppo; riesegui il deploy su un tenant gestito.
SCORE_CURSOR_UNSUPPORTED 400 startAfter è stato combinato con orderBy: "_score". La rilevanza viene calcolata per ogni query anziché memorizzata, quindi non può fungere da chiave per un cursore. Esegui la paginazione della rilevanza con limit/offset, oppure ordina in base a una colonna.
SQL_ERROR 400 Il database ha rifiutato SQL scritto da una persona. Tramite EXECUTE_SQL del socket realtime è un frame ERROR con il messaggio del database. Da 0.25 POST /api/admin/sql/csv risponde così prima che venga inviata qualsiasi parte del file: un errore di sintassi, una scrittura (il download viene eseguito in sola lettura), più di un’istruzione, o un ruolo che la connessione non può assumere. Correggi l’SQL. Un download accetta una sola SELECT, WITH … SELECT, TABLE o VALUES.
TENANT_IMMUTABLE 400 Una scrittura sposterebbe una riga da un tenant a un altro. Una riga non può cambiare tenant. details.violations indica il campo. Crea la riga nell’altro tenant ed elimina questa, oppure esegui la scrittura con un ruolo presente in tenant.bypassRoles.
TENANT_MISMATCH 400 La scrittura specifica un tenant a cui questo chiamante non appartiene; anche il database la rifiuterebbe. Scrivi in un tenant di cui il chiamante fa parte, oppure autenticati con un’identità che vi appartenga.
TENANT_REQUIRED 400 La collection è limitata a un tenant (tenant-scoped) e il tenant non può essere dedotto: la richiesta non ne specifica alcuno, oppure il chiamante appartiene a più tenant. Invia il campo tenant in modo esplicito, oppure autenticati come chiamante appartenente a un solo tenant.
TRANSACTION_ABORTED 500 Un’istruzione sulla transazione della scrittura è fallita e un callback ha intercettato l’errore. Postgres aveva già interrotto la transazione, quindi la scrittura è stata annullata e non è stato memorizzato nulla. Solo una context.data create, update o delete rifiutata dal database viene annullata da sola ed è sicuro intercettarla. Lascia che l’errore venga propagato, oppure effettua un controllo prima di eseguire l’istruzione. Consulta Semantica delle transazioni.
UNKNOWN_FIELD 400 ?fields= specifica un campo non presente nella collection. Verifica la correttezza del nome; il messaggio elenca i campi validi.
UNKNOWN_AGGREGATE_FIELD 400 Un aggregato o groupBy specifica un campo non presente nella collection. Verifica la correttezza del nome; il messaggio elenca i campi validi.
UNKNOWN_FILTER_FIELD 400 Il filtro specifica un campo non presente in questa collection — o nella destinazione di una relazione — oppure uno nascosto con excludeFromApi. Verifica la correttezza del nome; il messaggio elenca i campi validi.
UNKNOWN_FILTER_OPERATOR 400 Il filtro specifica un operatore inesistente. Il messaggio elenca tutti gli operatori disponibili.
UNKNOWN_MESSAGE_TYPE 400 Un frame del socket realtime ha un type che il server non gestisce. Risposta come frame ERROR con il requestId della richiesta, così la richiesta si chiude invece di andare in timeout. Controlla il type del frame; il messaggio lo nomina.
UNKNOWN_ORDER_BY_FIELD 400 L’ordinamento specifica un campo non presente nella collection. Verifica la correttezza del nome; il messaggio elenca i campi validi.
PRECONDITION_FAILED 412 Un header If-Match ha specificato una versione della riga non più attuale: qualcuno vi ha scritto tra la lettura e questa scrittura. Non è stato modificato nulla. Rileggi la riga, riapplica la modifica e invia il nuovo ETag.
UNKNOWN_RESPONSE_FIELD 400 ?fields= richiede un campo non presente nella collection. Verifica la correttezza del nome; il messaggio elenca i campi noti.
UNKNOWN_VECTOR_PROPERTY 400 Una ricerca vettoriale ha specificato una proprietà che non è di tipo vector in questa collection. Il messaggio elenca le proprietà vettoriali della collection.
UNSUPPORTED_MEDIA_TYPE 415 Il Content-Type non rientra tra quelli accettati da questa route. Invia il tipo indicato nella documentazione della route.
UNSUPPORTED_OPTION — Lanciato, non risposto: una scrittura tramite l’accessor in-process (context.data in un callback, rebase.data in una funzione o cron) ha ricevuto ifMatch oppure idempotencyKey. Quel canale non ha alcun controllo delle precondizioni né uno store di idempotenza, quindi l’opzione viene rifiutata prima che venga scritto qualcosa, invece di essere ignorata. Rimuovi l’opzione lì, oppure effettua la scrittura tramite il client HTTP, che rispetta entrambe.
UNSUPPORTED_RELATION_FILTER 400 Il filtro attraversa una relazione via, il cui percorso di join è configurato in una sola direzione, quindi non vi è alcun elemento con cui correlare una sottoquery all’indietro. Filtra dal lato proprietario della relazione.
UNSUPPORTED_RELATION_FILTER_OPERATOR 400 L’operatore non è definito per quel campo: una relazione senza una colonna su questa riga viene filtrata per appartenenza, e la corrispondenza di pattern (like, ilike e le loro negazioni) si applica solo al testo. Consulta il messaggio; elenca i valori accettati dal campo.
VALIDATION_CONSTRAINT 400 Un valore ha violato una regola di validation definita dalla proprietà — una lunghezza, un intervallo, un pattern, un campo obbligatorio. Consulta il messaggio; indica ciascuna violazione.
VALIDATION_EXCLUDED_FIELDS 400 Il corpo scrive su una colonna contrassegnata con excludeFromApi o access: { write: [] } — la stessa regola, con due sintassi diverse. Questi campi sono riservati all’impostazione da parte del server: l’hash di una password, un token di verifica. A differenza di FIELD_NOT_WRITABLE, questa risposta è identica per qualsiasi chiamante, admin compreso. Rimuovi il campo. Consulta Accesso ai campi.
VALIDATION_INVALID_VALUE 400 Un valore non corrisponde al tipo della proprietà. Consulta il messaggio; indica la proprietà interessata.
VALIDATION_UNKNOWN_FIELDS 400 Il corpo specifica un campo non presente nella collection — compreso un argomento id su una collection la cui chiave è basata su un altro campo. Verifica la correttezza del nome; il messaggio elenca i campi noti.
VECTOR_CURSOR_UNSUPPORTED 400 Un cursore (after / startAfter) è stato combinato con una ricerca vettoriale. Le righe sono ordinate per una distanza calcolata per ogni query, che non può fare da cursore, quindi un elenco vettoriale non ha nextCursor. Pagina le righe più vicine con limit/offset.
WRITE_DENIED 403 Una regola di sicurezza o una policy di row-level security ha rifiutato la scrittura. Controlla le securityRules della collection.

PG_<SQLSTATE> — un vincolo rifiutato dal database

Sezione intitolata “PG_<SQLSTATE> — un vincolo rifiutato dal database”

Una scrittura che Postgres rifiuta per un motivo legato ai dati del chiamante risponde con lo SQLSTATE nel codice: PG_23505, PG_23503 e così via. Si tratta di una famiglia di codici, non di un elenco esaustivo — Postgres definisce centinaia di SQLSTATE — ma solo due classi possono generarlo, poiché solo queste due dipendono dal chiamante:

  • classe 23, violazione del vincolo di integrità: un duplicato, una foreign key che punta al nulla, una colonna NOT NULL lasciata vuota;
  • classe 22, eccezione sui dati: un valore che il tipo della colonna non può contenere.

Tutto il resto — una connessione interrotta, una colonna mancante, un problema di privilegi — è responsabilità del server e rimane un errore 500. Pertanto code.startsWith("PG_") è un controllo affidabile per verificare se “la riga inviata era errata”, e i quattro codici riportati di seguito sono quelli che un client incontra concretamente. details.dbCode include lo stesso codice SQLSTATE per tutti, e il messaggio indica il vincolo violato.

Codice Stato Significato Cosa fare
PG_22P02 400 Un valore non può essere interpretato come il tipo della colonna — l’equivalente in scrittura di INVALID_FILTER_VALUE. Invia un valore corrispondente al tipo della colonna.
PG_23502 400 Una colonna NOT NULL è stata lasciata vuota. Invia il campo, oppure imposta un valore predefinito per la colonna.
PG_23503 400 Una foreign key fa riferimento a una riga inesistente. Crea prima la riga di destinazione, oppure correggi l’id.
PG_23505 409 È stato violato un vincolo di unicità. Il messaggio indica il vincolo violato. Usa un valore diverso, oppure aggiorna la riga esistente.
Codice Stato Significato Cosa fare
INVALID_LIST_OPTIONS 400 Il maxResults di un elenco dello storage non è un numero intero di almeno 1, o il suo pageToken non è stato emesso dalla sorgente. Una dimensione di pagina inferiore a uno restituiva una pagina vuota con lo stesso token, così un ciclo while (pageToken) non finiva mai. Invia un maxResults positivo e restituisci nextPageToken invariato.
INVALID_STORAGE_BUCKET 400 Il nome del bucket è malformato. Controlla il nome.
INVALID_STORAGE_KEY 400 La chiave dell’oggetto è malformata o esce dal prefisso consentito. Controlla la chiave.
INVALID_TRANSFORM_OPTIONS 400 I parametri di trasformazione dell’immagine sono fuori scala o contraddittori. Consulta Storage.
STORAGE_FILE_TOO_LARGE 413 L’upload supera la dimensione maxSize dichiarata dalla proprietà di destinazione. Applicato sul server, non solo nel browser. details indica la proprietà, il limite e la dimensione effettiva. Carica un file più piccolo, o aumenta maxSize sulla proprietà.
STORAGE_FILE_TYPE_REFUSED 400 Il tipo di file caricato non è presente tra i tipi ammessi (acceptedFiles) della proprietà, né tra gli allowedMimeTypes propri della sorgente di storage. details include la proprietà (o l’elenco della sorgente), l’elenco consentito e il content type inviato. Carica un tipo di file consentito, oppure amplia acceptedFiles / allowedMimeTypes.
STORAGE_MISCONFIGURED 502 Il bucket S3 o GCS con cui è configurata questa sorgente non esiste, oppure il provider ha rifiutato le credenziali di questo deployment per esso. Il messaggio nomina il bucket; details.reason è NoSuchBucket o il rifiuto del provider. Un bucket mancante veniva letto come «file non trovato» su ogni file. Correggi il nome del bucket (S3_BUCKET / GCS_BUCKET, __<KEY> per una sorgente con nome) o i permessi delle credenziali.
STORAGE_NOT_CONFIGURED 501 / 503 Nessun backend di storage è configurato su questo server, oppure nessuno è quello predefinito e la richiesta non nomina alcuna sorgente; il messaggio indica le sorgenti servite (501). Un caricamento riprendibile la cui sorgente è scomparsa prima della fine restituisce 503. Configura S3, GCS o lo storage locale, o nomina una sorgente con ?storageId=.
STORAGE_SCAN_INCOMPLETE 409 Da 0.25 DELETE /api/admin/storage/orphans (rebase storage orphans --delete) non ha potuto leggere ogni collection, quindi un file nominato da una di esse sembrerebbe inutilizzato. Non è stato eliminato nulla; details.unscanned nomina ogni collection e il motivo per cui non è stato possibile leggerla. Correggi ciò che impedisce la lettura di quelle collection ed eseguilo di nuovo.
STORAGE_SOURCE_NOT_CONFIGURED 501 La sorgente di storage è dichiarata ma non dispone di credenziali su questa istanza. Imposta le variabili d’ambiente per quella sorgente.
STORAGE_WRITE_FAILED 502 Il backend di storage ha rifiutato o interrotto la scrittura. Controlla i relativi log e le credenziali.
TRANSFORM_OVERLOADED 503 Troppe trasformazioni di immagini simultanee in esecuzione. Riprova; valuta l’uso di una CDN a monte.
UNKNOWN_STORAGE_SOURCE 400 / 404 La richiesta indica una sorgente di storage (?storageId=) non dichiarata da questo progetto. Un bucket non gestito da questo deployment restituisce lo stesso codice con stato 404 (su un elenco, e su un caricamento, una cartella o un caricamento riprendibile verso S3 o GCS) — ciò che manca è lo store, e details elenca i bucket e le sorgenti esistenti. In precedenza entrambi venivano segnalati come “file non trovato”, indistinguibili da una chiave semplicemente inesistente. Dichiara la sorgente in config/resources.ts, o controlla GET /api/storage/sources.
UPLOAD_LOCKED 423 Il PATCH di un caricamento riprendibile è arrivato mentre un altro chunk dello stesso caricamento era ancora in fase di ricezione — quasi sempre un client che ritenta il chunk già in corso. Viene rifiutato invece di essere messo in coda, come fa tusd. Richiedi l’offset con HEAD /api/storage/tus/:id e riprendi da lì; tus-js-client esegue il backoff e ritenta automaticamente. Vedi Caricamenti riprendibili TUS.
Codice Stato Significato Cosa fare
FUNCTION_NOT_FOUND 404 Nessuna funzione con questo nome è disponibile — o se lo è, le sue route non coprono il percorso successivo. A un chiamante autenticato viene anche indicato cosa è disponibile; a uno anonimo no, poiché tale elenco costituirebbe un inventario di tutti gli endpoint personalizzati. Se un file con quel nome non è stato caricato, il messaggio lo dice a un chiamante autenticato, nominando il file: questa è la differenza tra un errore di digitazione e un deploy non riuscito. Un chiamante anonimo riceve la semplice risposta di nome sconosciuto, come per un nome che non corrisponde a nulla. Confronta il nome con GET /api/functions, o controlla il log di avvio per individuare il file non caricato.
FUNCTION_TIMEOUT 504 L’handler ha superato il timeout previsto. L’esecuzione è ancora in corso; non può essere interrotta da qui. Assegna un AbortSignal alle chiamate in uscita, oppure aumenta REBASE_FUNCTIONS_TIMEOUT_MS.
FUNCTIONS_UPSTREAM_UNREACHABLE 502 Questo processo fa da proxy per le funzioni verso un altro processo, che non ha risposto. Verifica che l’unità delle funzioni sia in esecuzione.
Codice Stato Significato Cosa fare
CRON_JOB_ALREADY_EXECUTING 409 Un avvio manuale di un cron job già in esecuzione — nel processo che ha risposto, o in un altro che detiene il lease di esecuzione del job, come il worker dietro un processo api. Non è stato eseguito nulla. Il salto è nella cronologia del job, e details.log è quella voce; la sua riga indica il processo che esegue il job. Riprova quando quell’esecuzione è terminata. Vedi Cron job.

Superfici di amministrazione e modifica dello schema

Sezione intitolata “Superfici di amministrazione e modifica dello schema”

Questi codici indicano che una funzionalità è disattivata o non configurata, piuttosto che la richiesta fosse errata. Ciascuno di essi viene segnalato anche sulla route /status corrispondente con stato 200, consentendo a un pannello di disabilitare visivamente la funzione (in grigio) anziché mostrare un errore.

Codice Stato Significato Cosa fare
ADMIN_SURFACE_UNAVAILABLE 501 È stata chiamata una superficie riservata agli amministratori su un server senza autenticazione configurata, quindi non è possibile distinguere un amministratore da un utente anonimo. Imposta auth.jwtSecret, oppure passa un AuthAdapter.
CONTRACT_UNAVAILABLE 404 Il contratto del progetto viene fornito solo quando l’autenticazione è configurata — descrive ogni tabella e relazione. Configura l’autenticazione. /meta/schema-version è sempre disponibile.
DEV_MAILBOX_UNAVAILABLE 501 Nessuna casella di posta di sviluppo è attiva. Le email vengono acquisite solo quando SMTP_HOST non è impostato e NODE_ENV non è in produzione. Rimuovi SMTP_HOST in ambiente di sviluppo, oppure controlla la casella di posta reale.
INVALID_CHANGE 400 La modifica dello schema proposta non è ben formata. Consulta il messaggio.
SCHEMA_CHANGE_FAILED 400 L’applicazione di una modifica programmata dello schema non è riuscita per un motivo non coperto da codici più specifici. Consulta il messaggio; riporta testualmente l’errore sottostante.
SCHEMA_CHANGE_UNAPPLICABLE 400 La modifica è valida ma non può essere applicata allo schema nello stato attuale. Consulta il messaggio.
SCHEMA_EDIT_DIRTY_TREE 409 Il repository presenta modifiche non salvate (uncommitted), quindi la modifica non ha potuto essere applicata in modo sicuro. Esegui commit o stash, poi riprova.
SCHEMA_EDIT_REFUSED 400 L’editor di schema ha rifiutato la modifica. Consulta il messaggio; è il rifiuto esplicito dell’editor.
SCHEMA_EDIT_REQUIRES_A_PERSON 403 Una chiave API o un’altra identità automatizzata (machine principal) ha tentato di applicare una modifica allo schema. Accedi come utente, oppure imposta liveSchema.allowMachineApply.
SCHEMA_EDITING_NO_COLLECTIONS_DIR 501 La modifica dello schema dal vivo richiede collectionsDir o liveSchema.repository, e questo server è stato avviato senza nessuno dei due. Configura uno di essi.
SCHEMA_EDITING_NO_REPOSITORY 503 La pianificazione funziona; non è presente alcun repository in cui salvare (commit) la modifica. Configura liveSchema.repository.
SCHEMA_EDITING_UNSUPPORTED 503 Questo driver non è in grado di pianificare modifiche allo schema. La modifica dal vivo è disponibile su Postgres.
SCHEMA_EDITOR_BAAS_MODE 501 In questo ambiente le collection vengono ricavate per introspezione dal database, quindi non sono presenti file sorgente da modificare. Modifica lo schema tramite una migrazione.
SCHEMA_EDITOR_DISABLED 501 L’editor di schema è disabilitato per questo server. Un bundle compilato risponde sempre così. Abilitalo tramite schemaEditor. Su un bundle, imposta REBASE_LIVE_SCHEMA_REPOSITORY per modificare le collection tramite un repository — vedi Live schema editing.
SCHEMA_EDITOR_MISSING_DEPENDENCY 501 L’editor di schema necessita di ts-morph, che non è installato. Esegui pnpm add -D ts-morph@28.0.0.
SCHEMA_EDITOR_NO_COLLECTIONS_DIR 501 Il server non dispone di una collectionsDir, quindi l’editor non ha una destinazione in cui scrivere. Imposta collectionsDir.
SCHEMA_EDITOR_PRODUCTION 501 L’editor è disattivato quando NODE_ENV=production: i file di un server distribuito vengono ricompilati dal repository a ogni deploy, quindi una modifica qui andrebbe persa. Modifica le collection in sviluppo ed effettua il deploy, oppure configura liveSchema.repository per eseguirne il commit lì.
SQL_EXPORT_UNSUPPORTED 501 Da 0.25 POST /api/admin/sql/csv non può trasmettere un risultato qui: il database di sviluppo in-process (PGlite) ha una sola connessione, e un cursore tenuto aperto durante un download bloccherebbe ogni altra query; oppure la data source non ha un cursore SQL. Punta DATABASE_URL a un Postgres tuo (rebase dev --docker ne avvia uno), oppure aggiungi un LIMIT ed esporta le righe a schermo.

Una route utilizza uno di questi codici quando non è applicabile nulla di più specifico.

Codice Stato Significato Cosa fare
BAD_REQUEST 400 Malformata, e non si applica nulla di più specifico. Consulta il messaggio.
UNAUTHORIZED 401 Non autenticato, o la credenziale è stata rifiutata. Accedi o aggiorna il token.
FORBIDDEN 403 Autenticato, ma non autorizzato. Riprovare con la stessa identità non servirà.
CONFLICT 409 Conflitto con lo stato esistente. Consulta il messaggio.
INTERNAL_ERROR 500 Si è verificato un errore sul server. Il messaggio è generico per motivi di sicurezza. Riporta il requestId; il motivo è presente nei log.
NOT_CONFIGURED 503 Una dipendenza necessaria a questa route non è configurata su questo server. Consulta il messaggio.
SERVICE_UNAVAILABLE 503 Un servizio da cui dipende la richiesta non era raggiungibile: un bucket S3 o MinIO, oppure un host che una funzione raggiunge con fetch() e che rifiuta la connessione o non si risolve. Il log del server nomina l’host; la risposta no. Un database non raggiungibile è DATABASE_UNAVAILABLE. Da 0.25 Una connessione che fallisce verso un servizio simile risponde con questo codice; su 0.24 risponde con un 500 il cui codice è l’errore del socket (ECONNREFUSED), oppure INTERNAL_ERROR. Riprova; controlla i log.

pnpm verify:docs fallisce quando un codice che il server può generare è assente da queste tabelle, quando una tabella elenca un codice che nulla può generare, quando gli stati di una riga non sono esattamente quelli con cui il codice sorgente genera il codice o quando una famiglia di codici come PG_<SQLSTATE> non ha una riga per un codice SQLSTATE che i chiamanti possono incontrare. Lo stage di verifica è tooling/scripts/docs-verify/check-error-codes.mjs.

Esegue prima un controllo su se stesso. La scansione estrae i codici direttamente dal codice TypeScript anziché da un server in esecuzione, quindi i suoi punti ciechi sono per costruzione silenziosi: in passato non era in grado di rilevare un codice passato attraverso un wrapper a riga singola, o uno scritto dopo un messaggio contenente una ), e segnalava che “ogni codice generabile dal server è documentato” su una pagina a cui ne mancavano diciassette. Per questo motivo, lo stage esegue una fixture esattamente con queste casistiche prima di leggere questa pagina, e si rifiuta di segnalare qualsiasi esito se non riesce a individuarle.