{"record":{"id":"416c25ea157eaf6c","repo":"phacility/phabricator","slug":"failed-to-read-configuration-file-s","errorCode":null,"errorMessage":"Failed to read configuration file. %s","messagePattern":"Failed to read configuration file\\. (.+?)","errorType":"console","errorClass":"PhutilArgumentUsageException","httpStatus":null,"severity":"error","filePath":"src/applications/aphlict/management/PhabricatorAphlictManagementWorkflow.php","lineNumber":58,"sourceCode":"      foreach ($try as $config) {\n        $full_path = $root.'/'.$config;\n        $show_path = $config;\n        if (Filesystem::pathExists($full_path)) {\n          break;\n        }\n      }\n    }\n\n    echo tsprintf(\n      \"%s\\n\",\n      pht(\n        'Reading configuration from: %s',\n        $show_path));\n\n    try {\n      $data = Filesystem::readFile($full_path);\n    } catch (Exception $ex) {\n      throw new PhutilArgumentUsageException(\n        pht(\n          'Failed to read configuration file. %s',\n          $ex->getMessage()));\n    }\n\n    try {\n      $data = phutil_json_decode($data);\n    } catch (Exception $ex) {\n      throw new PhutilArgumentUsageException(\n        pht(\n          'Configuration file is not properly formatted JSON. %s',\n          $ex->getMessage()));\n    }\n\n    try {\n      PhutilTypeSpec::checkMap(\n        $data,\n        array(","sourceCodeStart":40,"sourceCodeEnd":76,"githubUrl":"https://github.com/phacility/phabricator/blob/5720a38cfe95b00ca4be5016dd0d2f3195f4fa04/src/applications/aphlict/management/PhabricatorAphlictManagementWorkflow.php#L40-L76","documentation":"Base class for Aphlict (notification server) management workflows fails while reading its JSON config: Filesystem::readFile($full_path) threw and the message is wrapped into a usage exception. The path is either the --config file given on the command line or the default candidate conf/aphlict/aphlict.custom.json / aphlict.default.json, where a missing default leaves $full_path pointing at a file that does not exist.","triggerScenarios":"Passing --config /path/that/does/not/exist.json; the file existing but unreadable to the web/CLI user (permissions); the default conf/aphlict/ directory lacking both aphlict.custom.json and aphlict.default.json so the fallback path is used and read fails.","commonSituations":"Fresh checkout or partial deploy where conf/aphlict defaults were never installed; permissions tightened so the daemon user cannot read the JSON; typo in the --config path in systemd unit or launch scripts.","solutions":["Check the exact path echoed by 'Reading configuration from:' and make that file exist and be readable (ls -l, run as the daemon user).","If using --config, verify the path is correct and absolute (or relative to the install root as resolved by Filesystem::resolvePath).","If relying on defaults, create phabricator/conf/aphlict/aphlict.custom.json copied from the shipped example/default so the default probe succeeds.","The wrapped %s carries the underlying reason (No such file / permission denied) - read it to pick between path vs permissions fixes."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"$full_path = Filesystem::resolvePath($config_file);\nif (!Filesystem::pathExists($full_path)) {\n  throw new Exception(\"Aphlict config not found at {$full_path}.\");\n}\nif (!is_readable($full_path)) {\n  throw new Exception(\"Aphlict config {$full_path} is not readable by this user.\");\n}\n// Safe to hand off to the management workflow.","typeGuard":null,"tryCatchPattern":"try {\n  // launch aphlict workflow\n} catch (PhutilArgumentUsageException $ex) {\n  if (preg_match('/Failed to read configuration file/', $ex->getMessage())) {\n    // The wrapped %s is the underlying Filesystem error: missing file vs permissions.\n    // Fix path/ownership, then retry once; do not loop.\n  }\n  throw $ex;\n}","preventionTips":["Pass an absolute --config path in systemd/launch scripts to avoid cwd-dependent resolution.","Ensure conf/aphlict/aphlict.custom.json exists (copy from the shipped default) on fresh installs.","Run daemon launch as the user that owns/reads the config; verify with ls -l and sudo -u <user> cat.","Lint deploy checklists with a simple file_exists + is_readable assertion on the config path."],"tags":["aphlict","notifications","config","file-io","phabricator"],"backgroundTag":"config-file-read-failure","analyzedSha":"5720a38cfe95b00ca4be5016dd0d2f3195f4fa04","analyzedAt":"2026-08-21T05:07:25.672Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}