{"record":{"id":"238b54f3467eb25c","repo":"phacility/phabricator","slug":"err-bad-file","errorCode":"ERR-BAD-FILE","errorMessage":"ERR-BAD-FILE","messagePattern":"ERR-BAD-FILE","errorType":"error_code","errorClass":"ConduitException","httpStatus":null,"severity":"error","filePath":"src/applications/differential/conduit/DifferentialCreateInlineConduitAPIMethod.php","lineNumber":95,"sourceCode":"      // Given neither, bail.\n      throw new ConduitException('ERR-NEED-DIFF');\n    }\n\n    $file = $request->getValue('filePath');\n    if (!$file) {\n      throw new ConduitException('ERR-NEED-FILE');\n    }\n    $changes = id(new DifferentialChangeset())->loadAllWhere(\n      'diffID = %d',\n      $did);\n    $cid = null;\n    foreach ($changes as $id => $change) {\n      if ($file == $change->getFilename()) {\n        $cid = $id;\n      }\n    }\n    if ($cid == null) {\n      throw new ConduitException('ERR-BAD-FILE');\n    }\n\n    $inline = id(new DifferentialInlineComment())\n      ->setRevisionID($rid)\n      ->setChangesetID($cid)\n      ->setAuthorPHID($request->getUser()->getPHID())\n      ->setContent($request->getValue('content'))\n      ->setIsNewFile((int)$request->getValue('isNewFile'))\n      ->setLineNumber($request->getValue('lineNumber'))\n      ->setLineLength($request->getValue('lineLength', 0))\n      ->save();\n\n    // Load everything again, just to be safe.\n    $changeset = id(new DifferentialChangeset())\n      ->load($inline->getChangesetID());\n    return $this->buildInlineInfoDictionary($inline, $changeset);\n  }\n","sourceCodeStart":77,"sourceCodeEnd":113,"githubUrl":"https://github.com/phacility/phabricator/blob/5720a38cfe95b00ca4be5016dd0d2f3195f4fa04/src/applications/differential/conduit/DifferentialCreateInlineConduitAPIMethod.php#L77-L113","documentation":"Thrown by differential.createinline after the diff's changesets are loaded (DifferentialChangeset where diffID matches). The method compares filePath to each changeset's getFilename() with exact equality (last match wins) and records the matching changeset ID. If no changeset filename equals filePath, it throws ConduitException('ERR-BAD-FILE').","triggerScenarios":"Passing a path that does not exactly equal a changeset filename: absolute paths where the diff stores relative ones, a leading './' or '/', Windows backslash separators, a renamed file's old name, or a file that is simply not touched by that diff.","commonSituations":"Lint bots reporting paths from a different working-copy root; comments targeted at a file changed only in a newer diff than the one being commented on; tools normalizing paths differently than git/arc did when the diff was uploaded.","solutions":["Fetch the exact filename list first (differential.getcommitpaths for the revision, or the changesets from differential.getdiff) and send a value from that list","Strip leading slashes, './' segments, and convert separators to match the diff's relative paths","When commenting on a specific diff, take the path from that same diff's changesets, not from the working copy","If the file is not in the diff, attach the note as a plain comment instead of an inline"],"exampleFix":"// before\n$params = array(\n  'revisionID' => 789,\n  'filePath' => '/home/ci/repo/src/app.php',\n);\n\n// after\n$params = array(\n  'revisionID' => 789,\n  'filePath' => 'src/app.php', // exact match against the changeset filename\n);","handlingStrategy":"validation","validationCode":"// Match exactly against the diff's own changeset filenames.\n$paths = $client->callMethodSynchronous('differential.getcommitpaths',\n  array('revision_id' => (int)$rid));\nif (!in_array($params['filePath'], $paths, true)) {\n  $params['filePath'] = pickClosest($paths, $params['filePath']); // or skip\n}","typeGuard":null,"tryCatchPattern":"try {\n  $client->callMethodSynchronous('differential.createinline', $params);\n} catch (ConduitClientException $ex) {\n  if ($ex->getErrorCode() === 'ERR-BAD-FILE') {\n    // path not in this diff: post a revision-level comment instead\n  } else {\n    throw $ex;\n  }\n}","preventionTips":["Normalize paths (no leading '/', no './', forward slashes) to the diff's convention","Derive comment paths from the same diff being commented on","Exact-match check against the changeset list before submitting"],"tags":["phabricator","conduit","differential","inline-comment","path-mismatch"],"backgroundTag":"invalid-parameter-value","analyzedSha":"5720a38cfe95b00ca4be5016dd0d2f3195f4fa04","analyzedAt":"2026-08-21T05:07:25.672Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}