Repository navigation
fix: Prevent infinite recursion in CommentsEntry::record() closures - #118
Merged
Merged
Conversation
`record()` proxied to Filament's `model()`, which stores the value on the
component's `$model`. `BelongsToModel::getRecord()` evaluates `$model`, and
Filament resolves a closure's `$record` parameter (by name, or by any Model
type-hint) by calling `getRecord()` again — so any closure referencing the
record recursed until memory was exhausted:
CommentsEntry::make('comments')
->record(fn (Prerequisite $record) => $pivot)
Allowed memory size of 134217728 bytes exhausted
Only the documented parameterless form (`fn () => $pivot`) and plain model
instances worked, which is why this went unnoticed.
The override is now stored on its own property and resolved in an overridden
`getRecord()` guarded against re-entry, so a nested lookup returns the
container record instead of recursing. Closures may now type-hint or name a
`$record` parameter and receive the page record.
Fixes #116
Claude-Session: https://claude.ai/code/session_01Qy9u3fiaQQJsTyE6PxRdK6
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
Reported in #116: using
CommentsEntry::record()with a closure blows the memory limit.Root cause
It's infinite recursion, not a leak.
record()proxied to Filament'smodel(), which stores the value on the component's$model.BelongsToModel::getRecord()then evaluates$model, and Filament resolves a closure's parameters viaComponent::resolveDefaultClosureDependencyForEvaluationByName(), where'record' => [$this->getRecord()].So
getRecord()→ evaluate closure → needs$record→getRecord()→ … Reproduced locally with 136,000+ stack frames and the exact error from the report.The trigger is the closure's signature, not its body. It recurses if the parameter is named
$record(by-name match) or type-hinted with any Model subclass (by-type match). The reported snippet hits both.This went unnoticed because the documented form is parameterless (
fn () => $pivot) and the existing test passes a plain model instance — both of which work fine.Fix
Store the override on its own property instead of
$this->model, and resolve it in an overriddengetRecord()guarded against re-entry. While the override is resolving, a nestedgetRecord()returns the container record rather than recursing.The guard covers every injection path rather than just the two known ones, so closures type-hinting an intermediate parent class are handled too. As a side effect,
$recordinside the closure now resolves to the container (page) record, which is what the reported snippet already assumed.Tests
New
tests/Filament/CommentsEntryRecordTest.phpcovers:$recordparameter$recordresolving to the container recordThe first four fail on
mainwith the reported memory exhaustion; all pass with the fix.Full suite: 169 passed. Pint clean. PHPStan unchanged — the 7 pre-existing errors in
tests/Livewire/CommentReactionTest.phpare also present onmain.Not addressed
The same comment reports a second, unrelated issue: no way to remove attachments when editing an existing comment. That's a separate gap — the attachment UI is only included in the new-comment form, and
Livewire\Comment::updateComment()has no attachment handling at all, so attachments can be neither added nor removed while editing. Worth its own issue.https://claude.ai/code/session_01Qy9u3fiaQQJsTyE6PxRdK6