{"record":{"id":"cc3bfdd440e7c71a","repo":"coollabsio/coolify","slug":"preview-not-found","errorCode":null,"errorMessage":"Preview not found","messagePattern":"Preview not found","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"warning","filePath":"app/Livewire/Project/Application/Previews.php","lineNumber":113,"sourceCode":"    public function confirmDomainUsage()\n    {\n        $this->forceSaveDomains = true;\n        $this->showDomainConflictModal = false;\n        if ($this->pendingPreviewId) {\n            $this->save_preview($this->pendingPreviewId);\n            $this->pendingPreviewId = null;\n        }\n    }\n\n    public function save_preview($preview_id)\n    {\n        try {\n            $this->authorize('update', $this->application);\n            $success = true;\n            $preview = $this->application->previews->find($preview_id);\n\n            if (! $preview) {\n                throw new \\Exception('Preview not found');\n            }\n\n            // Find the key for this preview in the collection\n            $previewKey = $this->application->previews->search(function ($item) use ($preview_id) {\n                return $item->id == $preview_id;\n            });\n\n            if ($previewKey !== false && isset($this->previewFqdns[$previewKey])) {\n                $this->validate([\n                    \"previewFqdns.{$previewKey}\" => ValidationPatterns::applicationDomainRules(),\n                ]);\n\n                $fqdn = $this->previewFqdns[$previewKey];\n\n                if (! empty($fqdn)) {\n                    $fqdn = ValidationPatterns::normalizeApplicationDomains($fqdn);\n                    $this->previewFqdns[$previewKey] = $fqdn;\n","sourceCodeStart":95,"sourceCodeEnd":131,"githubUrl":"https://github.com/coollabsio/coolify/blob/70b9acc42467278373e00de77abb40684e25b395/app/Livewire/Project/Application/Previews.php#L95-L131","documentation":"save_preview() looks up a PR preview by id inside $this->application->previews before saving its domains. A null result - the preview was deleted, rolled back, or the id comes from stale browser state - throws before any FQDN validation or update runs.","triggerScenarios":"Calling save_preview with a preview_id that is not in the application's previews relation: the preview deployment was deleted in another tab, the PR was closed and cleaned up, or the browser table row is stale.","commonSituations":"Long-open preview panels; concurrent users closing previews; Livewire table state surviving preview deletion; re-submitting an edit form after the preview was destroyed.","solutions":["Refresh the previews panel so it lists only live previews","Confirm the preview still exists (application > Previews / pull requests) before editing its domains","Close duplicate tabs editing the same preview"],"exampleFix":"// before\n$preview = $this->application->previews->find($preview_id);\nif (! $preview) {\n    throw new \\Exception('Preview not found');\n}\n// after\n$preview = $this->application->previews->find($preview_id);\nif (! $preview) {\n    $this->dispatch('error', 'This preview no longer exists. Refresh the list.');\n    return;\n}","handlingStrategy":"validation","validationCode":"// before saving, confirm the preview still exists for this application\nif (! $this->application->previews()->whereKey($previewId)->exists()) {\n    $this->dispatch('error', 'Preview no longer exists - refresh the list.');\n    return;\n}","typeGuard":"function previewBelongsToApplication($application, int|string $previewId): bool\n{\n    return $application->previews()->whereKey($previewId)->exists();\n}","tryCatchPattern":null,"preventionTips":["Refresh the previews panel after closing/deleting PR previews elsewhere","Guard stale row actions with an exists() check and bail with a friendly message","Avoid keeping edit forms for previews open across long sessions"],"tags":["livewire","preview","pull-request","stale-state"],"backgroundTag":"stale-record-reference","analyzedSha":"70b9acc42467278373e00de77abb40684e25b395","analyzedAt":"2026-08-17T01:41:01.313Z","schemaVersion":2},"datasetVersion":"2026-08-17T04:17:16.089Z"}