{"record":{"id":"4d1abafc723c4be8","repo":"phacility/phabricator","slug":"api-method-s-defines-a-disallowed-parameter","errorCode":null,"errorMessage":"API Method \"%s\" defines a disallowed parameter, \"%s\". This parameter name is reserved.","messagePattern":"API Method \"(.+?)\" defines a disallowed parameter, \"(.+?)\"\\. This parameter name is reserved\\.","errorType":"validation","errorClass":"ConduitException","httpStatus":null,"severity":"error","filePath":"src/applications/conduit/call/ConduitCall.php","lineNumber":26,"sourceCode":" *   $result = $call->execute();\n *\n */\nfinal class ConduitCall extends Phobject {\n\n  private $method;\n  private $handler;\n  private $request;\n  private $user;\n\n  public function __construct($method, array $params, $strictly_typed = true) {\n    $this->method = $method;\n    $this->handler = $this->buildMethodHandler($method);\n\n    $param_types = $this->handler->getParamTypes();\n\n    foreach ($param_types as $key => $spec) {\n      if (ConduitAPIMethod::getParameterMetadataKey($key) !== null) {\n        throw new ConduitException(\n          pht(\n            'API Method \"%s\" defines a disallowed parameter, \"%s\". This '.\n            'parameter name is reserved.',\n            $method,\n            $key));\n      }\n    }\n\n    $invalid_params = array_diff_key($params, $param_types);\n    if ($invalid_params) {\n      throw new ConduitException(\n        pht(\n          'API Method \"%s\" does not define these parameters: %s.',\n          $method,\n          \"'\".implode(\"', '\", array_keys($invalid_params)).\"'\"));\n    }\n\n    $this->request = new ConduitAPIRequest($params, $strictly_typed);","sourceCodeStart":8,"sourceCodeEnd":44,"githubUrl":"https://github.com/phacility/phabricator/blob/5720a38cfe95b00ca4be5016dd0d2f3195f4fa04/src/applications/conduit/call/ConduitCall.php#L8-L44","documentation":"ConduitCall's constructor checks every parameter a method declares in defineParamTypes() against ConduitAPIMethod::getParameterMetadataKey(). Names starting with 'api.', plus access_token, scope, output, __conduit__, code, and params, are reserved for protocol metadata and alternate decoding pathways — a method defining one would let clients inject transport-level data, so construction aborts.","triggerScenarios":"Writing a ConduitAPIMethod subclass whose defineParamTypes() returns a spec containing e.g. 'params', 'code', 'output', 'scope', 'access_token', or any 'api.*' key; the exception fires the first time that method is constructed by a ConduitCall.","commonSituations":"Newly authored conduit methods during development (the error appears in tests or the first live call); wrappers that build parameter specs from external schemas without filtering reserved words; methods refactored so a user-facing parameter got renamed to a reserved name.","solutions":["Rename the offending parameter to something not in the reserved set (e.g. 'output' -> 'outputFormat')","Filter generated parameter specs against ConduitAPIMethod::getParameterMetadataKey() before shipping them","Add a unit test that constructs each new method via ConduitCall so reserved names fail in CI, not production"],"exampleFix":"// before\npublic function defineParamTypes() {\n  return array(\n    'output' => 'required string',\n  );\n}\n\n// after\npublic function defineParamTypes() {\n  return array(\n    'outputFormat' => 'required string',\n  );\n}","handlingStrategy":"validation","validationCode":"foreach (array_keys($param_types) as $key) {\n  if (ConduitAPIMethod::getParameterMetadataKey($key) !== null) {\n    throw new Exception(\n      'Parameter name reserved by conduit protocol: '.$key);\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n  $call = new ConduitCall($method_name, $params);\n} catch (ConduitException $ex) {\n  // Method-definition bug: fail the developer's test run with the message.\n  $this->fail('Reserved parameter name in '.$method_name.': '.$ex->getMessage());\n}","preventionTips":["Learn the reserved set: 'api.*' prefixes plus access_token, scope, output, __conduit__, code, params","Add a CI test that instantiates every ConduitAPIMethod through ConduitCall to catch bad specs early","When generating method specs from schemas, filter keys through getParameterMetadataKey()"],"tags":["phabricator","conduit","api","reserved-words","parameter-validation"],"backgroundTag":"reserved-parameter-name","analyzedSha":"5720a38cfe95b00ca4be5016dd0d2f3195f4fa04","analyzedAt":"2026-08-21T05:07:25.672Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}