L’approvazione di un argomento in coda sul nostro sito self-hosted è fallita con HTTP 500 perché il record in coda conteneva payload.tags = "macos" (una stringa). Il valore malformato era già stato accettato da POST /posts.
Comprendo che i client dovrebbero inviare un array di tag. Il problema che sto segnalando è che uno scalare non valido può essere accettato nella coda di revisione e fallire solo successivamente, quando un moderatore approva il post.
Versione: 2026.10.0-latest, commit 3f2bf92368c78a7fa9a755f3d046adf35dd4459b.
Evidenze dall’incidente
Il post richiedeva approvazione a causa di approve_post_count.
Alle 13:37:52 UTC del 2026-10-22, i parametri della richiesta Rails originale contenevano già:
"tags" => "macos"
La richiesta era POST /posts e il corrispondente access log ha registrato HTTP 200. I nomi dei parametri inviati erano title, raw, category e tags.
La lettura della reviewable pendente ha confermato:
{
"type": "ReviewableQueuedPost",
"status": 0,
"version": 0,
"topic_id": null,
"payload": {
"tags": "macos"
}
}
Questa è un’estrazione dei campi rilevanti, con titolo, corpo e informazioni utente omessi. L’interfaccia di revisione mostrava il tag come cinque lettere separate: m, a, c, o, s.
Il clic su Approva ha prodotto questa eccezione (cinque occorrenze raggruppate nei log):
NoMethodError (undefined method '-' for an instance of String)
lib/discourse_tagging.rb:932:in 'DiscourseTagging.tags_for_saving'
lib/discourse_tagging.rb:43:in 'DiscourseTagging.tag_topic_by_names'
lib/discourse_tagging.rb:30:in 'DiscourseTagging.tag_topic'
lib/topic_creator.rb:228:in 'TopicCreator#setup_tags'
lib/topic_creator.rb:60:in 'TopicCreator#create'
lib/post_creator.rb:519:in 'PostCreator#create_topic'
lib/post_creator.rb:209:in 'block in PostCreator#create'
lib/post_creator.rb:419:in 'block in PostCreator#transaction'
lib/post_creator.rb:419:in 'PostCreator#transaction'
lib/post_creator.rb:207:in 'PostCreator#create'
app/models/reviewable_queued_post.rb:110:in 'ReviewableQueuedPost#perform_approve_post'
app/models/reviewable.rb:433:in 'Kernel#public_send'
app/models/reviewable.rb:433:in 'block in Reviewable#perform'
app/models/reviewable.rb:431:in 'Reviewable#perform'
app/controllers/reviewables_controller.rb:287:in 'ReviewablesController#perform'
Codice rilevante
Questi sono i percorsi di codice verificati nel container in esecuzione al commit sopra indicato:
- PostsController#create_params chiama
params.permit(tags: %i[id name]), ma non utilizza i parametri filtrati restituiti. Assegna quindi il valore originale conresult[f] = params[f]. - NewPostManager#enqueue copia direttamente
@args[:tags]nel payload della reviewable. - ReviewableQueuedPost#create_options converte i tag solo se il valore è già un Array, lasciando invariata una stringa scalare.
- DiscourseTagging.tags_for_saving valuta poi
tags_arg - tag_namesquando l’utente che approva può creare tag, il che genera un errore per una stringa.
Comportamento atteso
Rifiutare un parametro tags scalare con un chiaro errore di validazione prima di creare la reviewable, oppure normalizzarlo se questo è il comportamento di compatibilità previsto. Una reviewable malformata esistente dovrebbe inoltre fallire in modo elegante invece di causare un 500 non gestito durante la moderazione.
Soluzione temporanea e limiti di questa segnalazione
La modifica della reviewable, la rimozione del vecchio tag, la selezione del tag macos esistente e il salvataggio hanno modificato payload.tags in un array di oggetti tag. La rilettura ha confermato versione 1, ancora pendente, e l’interfaccia mostrava di nuovo un tag. Non ho riprovato l’approvazione dopo tale modifica.
Il client del mittente originale è sconosciuto. Questa segnalazione non stabilisce che il composer nativo generi tag scalari. Si basa sulla richiesta effettiva, sulla reviewable archiviata, sull’eccezione e sul codice ispezionato; non l’ho riprodotta separatamente su un’installazione pulita.
Per una riproduzione in ambiente di sviluppo, il percorso da testare è: richiedere l’approvazione per un post di un utente non staff, inviare POST /posts con uno scalare tags: "macos" e altri campi validi, quindi approvare il post in coda risultante come amministratore.
C’è una discussione API più vecchia con la stessa eccezione di sottrazione di String. Questa segnalazione si concentra sul fatto che il valore non valido venga accettato nella coda di revisione e rompa l’approvazione in seguito.