{"record":{"id":"28b537608d1dbbb2","repo":"octobercms/october","slug":"system-lang-project-id-missing","errorCode":"system::lang.project.id.missing","errorMessage":"Please specify a Project ID to use.","messagePattern":"Please specify a Project ID to use\\.","errorType":"validation","errorClass":"ValidationException","httpStatus":null,"severity":"warning","filePath":"modules/system/controllers/Updates.php","lineNumber":243,"sourceCode":"        return 'positive';\n    }\n\n    /**\n     * onLoadProjectForm displays the form for entering a license key\n     */\n    public function onLoadProjectForm()\n    {\n        return $this->makePartial('project_form');\n    }\n\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","sourceCodeStart":225,"sourceCodeEnd":261,"githubUrl":"https://github.com/octobercms/october/blob/b608633a7e8922487d91a8161499020121c3b3bf/modules/system/controllers/Updates.php#L225-L261","documentation":"onAttachProject is the AJAX handler behind Settings > System > Updates > Attach project. It reads post('project_id') and throws a ValidationException bound to the project_id field when the value is empty after trim(), so the backend redisplays the form with the field highlighted instead of contacting the gateway.","triggerScenarios":"Submitting the attach-project form with an empty or whitespace-only project ID; a customized form that no longer posts a field named project_id; the input removed by a browser extension or failed autofill.","commonSituations":"User submits the modal too early; custom-themed backend form renamed the input; JS validation disabled.","solutions":["Enter the Project ID from your octobercms.com account/client area and resubmit","If the form was customized, ensure the input is named exactly project_id (the handler reads post('project_id'))","Paste the ID without surrounding whitespace; trim() handles it but empty-after-trim still fails"],"exampleFix":"<!-- before: field name mismatch, handler receives nothing -->\n<input type=\"text\" name=\"projectId\">\n\n<!-- after -->\n<input type=\"text\" name=\"project_id\">","handlingStrategy":"validation","validationCode":"// client-side, before the AJAX submit\nconst id = document.querySelector('input[name=project_id]').value.trim();\nif (!id) { alert('Project ID is required'); return; }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep the input named project_id; the handler reads post('project_id')","Paste the Project ID from the octobercms.com account page, not from emails","Leave client-side required validation enabled on the attach-project modal"],"tags":["validation","project-id","updates","backend-form"],"backgroundTag":"required-field-missing","analyzedSha":"b608633a7e8922487d91a8161499020121c3b3bf","analyzedAt":"2026-08-21T04:24:57.515Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}