{"record":{"id":"ea46c1ef6e8b585c","repo":"octobercms/october","slug":"invalid-json-error","errorCode":null,"errorMessage":"Invalid JSON: :error","messagePattern":"Invalid JSON: :error","errorType":"validation","errorClass":"ValidationException","httpStatus":null,"severity":"warning","filePath":"modules/system/controllers/updates/HasComposerEditor.php","lineNumber":38,"sourceCode":"        $widget->getField('content')->value(File::get($composerFile));\n\n        $this->vars['widget'] = $widget;\n\n        return $this->makePartial('composer_form');\n    }\n\n    /**\n     * manage_onSaveComposer validates and saves the composer.json file\n     */\n    public function manage_onSaveComposer()\n    {\n        $content = post('Composer')['content'] ?? '';\n\n        try {\n            json_decode($content, flags: JSON_THROW_ON_ERROR);\n        }\n        catch (\\JsonException $ex) {\n            throw new ValidationException(['content' => __(\"Invalid JSON: :error\", [\n                'error' => $ex->getMessage()\n            ])]);\n        }\n\n        File::put(base_path('composer.json'), $content);\n\n        Flash::success(__(\"Composer file updated successfully.\"));\n    }\n\n    /**\n     * makeComposerFormWidget creates a form widget for the composer editor\n     */\n    protected function makeComposerFormWidget()\n    {\n        $config = $this->makeConfig([\n            'alias' => 'formComposerEditor',\n            'arrayName' => 'Composer',\n            'model' => new \\Model,","sourceCodeStart":20,"sourceCodeEnd":56,"githubUrl":"https://github.com/octobercms/october/blob/b608633a7e8922487d91a8161499020121c3b3bf/modules/system/controllers/updates/HasComposerEditor.php#L20-L56","documentation":"The backend composer.json editor (Updates > Manage projects) saves through manage_onSaveComposer. It runs json_decode($content, JSON_THROW_ON_ERROR) and converts any JsonException into a ValidationException on the content field with the message 'Invalid JSON: <parser error>'. File::put(base_path('composer.json'), ...) only runs after the content parses cleanly.","triggerScenarios":"Saving composer.json with a trailing comma, single-quoted strings, unquoted keys, smart quotes, an unterminated object, or an empty string (post('Composer')['content'] defaults to '' which also fails json_decode with 'Syntax error').","commonSituations":"Hand-editing composer.json in the UI and forgetting JSON strictness; pasting YAML-ish config; submitting the form with a cleared textarea.","solutions":["Fix the syntax error named in the JsonException message (it includes the position)","Validate before saving: JSON.parse the content client-side, or run it through jsonlint","For intentionally empty content, save a minimal valid document such as {} instead of blank text"],"exampleFix":"// before\n{\n    \"require\": {\n        \"october/system\": \"^3.0\",\n    }\n}\n\n// after\n{\n    \"require\": {\n        \"october/system\": \"^3.0\"\n    }\n}","handlingStrategy":"validation","validationCode":"// server-side, before saving\ntry { json_decode($content, flags: JSON_THROW_ON_ERROR); } catch (\\JsonException $ex) { /* block save, show $ex->getMessage() */ }\n\n// client-side\ntry { JSON.parse(content); } catch (e) { /* block submit */ }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never allow blank submissions; substitute {} for empty content","Run JSON.parse in the editor before enabling the save button","Remember composer.json is strict JSON: no trailing commas, no single quotes, no comments"],"tags":["json","composer","validation","backend"],"backgroundTag":"json-parse-error","analyzedSha":"b608633a7e8922487d91a8161499020121c3b3bf","analyzedAt":"2026-08-21T04:24:57.515Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}