Conversation
…Expression DialogMessage::creating() sets $message->number to a raw DB Expression object — a subquery that computes COALESCE(MAX(number), 0) + 1 — which Eloquent embeds directly into the INSERT statement for atomic, race-condition-safe message numbering. Unlike Post::created (which calls $post->refresh() in its Eloquent boot hook), DialogMessage had no equivalent cleanup. When the API's Create endpoint serialized the newly-created DialogMessage in the response, $model->number was still the Expression object. Eloquent's integer cast then attempted (int) $expression, producing: ErrorException: Object of class Illuminate\Database\Query\Expression could not be converted to int On PHP 8.3 this is a warning (coerced to 0); on the production server Sentry's error handler promotes PHP warnings to ErrorExceptions, which is why the error appears in the log on every message send. Fix: call $model->refresh() at the top of DialogMessageResource::created() to re-query the DB and replace the Expression with the real integer before any further processing or serialization occurs. Regression test added to CreateTest to assert the response number attribute is a concrete integer, not a coerced zero from a failed cast. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Every time a user sends a private message, the following error is logged:
Root Cause
DialogMessage::creating()sets$message->numberto a rawDB Expressionobject — a subquery that computesCOALESCE(MAX(number), 0) + 1— which Eloquent embeds directly in the INSERT statement for atomic, race-condition-safe message numbering within a dialog. This mirrors the same pattern used inPost::creating().The problem is that
Posthas a correspondingPost::created()Eloquent boot hook that calls$post->refresh()to replace the Expression with the real integer value from the DB.DialogMessagehas no such hook.When the API's
Createendpoint serializes the newly-createdDialogMessagein the response,$model->numberis still theExpressionobject. Eloquent'sintegercast then attempts(int) $expression, which:0, so the response returns"number": 0)ErrorException, causing every message send to log an errorFix
Call
$model->refresh()at the top ofDialogMessageResource::created(). This re-queries the database on the write PDO connection and replaces theExpressionwith the actual integer before any further processing or serialization.Test
Added
test_created_message_response_contains_integer_number_not_expressiontoCreateTest. Before the fix, this test triggers the PHP warning (confirming the bug). After the fix, all 3 tests pass cleanly with no warnings.