{"record":{"id":"cc5acce063b5352c","repo":"octobercms/october","slug":"license-is-unpaid-or-has-expired-please-visit-oct","errorCode":null,"errorMessage":"License is unpaid or has expired. Please visit octobercms.com to obtain a license.","messagePattern":"License is unpaid or has expired\\. Please visit octobercms\\.com to obtain a license\\.","errorType":"validation","errorClass":"ValidationException","httpStatus":null,"severity":"error","filePath":"modules/system/controllers/Updates.php","lineNumber":253,"sourceCode":"\n    /**\n     * onAttachProject validates the project ID and execute the project installation\n     */\n    public function onAttachProject()\n    {\n        try {\n            if (!$projectId = trim(post('project_id'))) {\n                throw new ValidationException(['project_id' => Lang::get('system::lang.project.id.missing')]);\n            }\n\n            // Validate input with gateway\n            $manager = UpdateManager::instance();\n            $result = $manager->requestProjectDetails($projectId);\n\n            // Check project status\n            $isActive = $result['is_active'] ?? false;\n            if (!$isActive) {\n                throw new ValidationException(['project_id' => __(\"License is unpaid or has expired. Please visit octobercms.com to obtain a license.\")]);\n            }\n\n            // Store project details\n            $manager->storeProjectDetails($result);\n\n            // Add gateway as a composer repo\n            $this->ensureComposerRegistered();\n\n            Flash::success(__(\"Thanks for being a customer of October CMS!\"));\n            return Backend::redirect('system/updates');\n        }\n        catch (Exception $ex) {\n            throw new ValidationException(['project_id' => $ex->getMessage()]);\n        }\n    }\n\n    /**\n     * Make sure composer is ready to receive updates","sourceCodeStart":235,"sourceCodeEnd":271,"githubUrl":"https://github.com/octobercms/october/blob/b608633a7e8922487d91a8161499020121c3b3bf/modules/system/controllers/Updates.php#L235-L271","documentation":"When attaching a project, October validates the ID against the gateway via UpdateManager::requestProjectDetails($projectId). If the response's is_active flag is falsy (defaults to false when absent), a ValidationException on project_id states the license is unpaid or expired. The gateway will not serve composer packages for that project until the license is active, so attach is refused before storeProjectDetails/ensureComposerRegistered run.","triggerScenarios":"onAttachProject with a syntactically valid Project ID whose license is inactive: expired annual license, unpaid invoice, refunded/trial ended, or an ID belonging to a different account.","commonSituations":"License lapsed mid-project; developer copied the wrong project ID from the account dashboard; purchase not yet provisioned on the gateway.","solutions":["Log in at octobercms.com, open the account/project page and check the license status; renew or pay if lapsed, then retry attaching","Verify you copied the correct Project ID for this project (not another project's)","If the license clearly shows active, contact October CMS support or check gateway status before retrying"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"$result = \\UpdateManager::instance()->requestProjectDetails($projectId);\nif (!($result['is_active'] ?? false)) {\n    // surface a billing warning and stop before attaching the project\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep the October CMS license active; check its status on the account dashboard before debugging","Verify the Project ID belongs to the account you expect","Treat is_active=false as a hard stop: composer operations against the gateway will fail"],"tags":["license","billing","project-id","updates"],"backgroundTag":"license-expired","analyzedSha":"b608633a7e8922487d91a8161499020121c3b3bf","analyzedAt":"2026-08-21T04:24:57.515Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}