go-gitea/gitea · error

Failed to update PR target branch: ${resp.statusText}

Error message

Failed to update PR target branch: ${resp.statusText}

What it means

Thrown in the same submit handler as the title update, one step later: after a PR title saves successfully, if the edited PR target branch differs from the old one the client POSTs to the data-target-update-url (POST /{owner}/{repo}/pulls/{index}/target_branch). A non-2xx response aborts the whole save with this message; note the title change may already have been applied.

Source

Thrown at web_src/js/features/repo-issue.ts:419

  const editSaveButton = issueTitleEditor.querySelector('.ui.primary.button')!;
  issueTitleEditor.addEventListener('submit', async (e) => {
    e.preventDefault();
    const newTitle = issueTitleInput.value.trim();
    try {
      if (newTitle && newTitle !== oldTitle) {
        const resp = await POST(editSaveButton.getAttribute('data-update-url')!, {data: new URLSearchParams({title: newTitle})});
        if (!resp.ok) {
          throw new Error(`Failed to update issue title: ${resp.statusText}`);
        }
      }
      if (prTargetUpdateUrl) {
        const newTargetBranch = document.querySelector('#pull-target-branch')!.getAttribute('data-branch');
        const oldTargetBranch = document.querySelector('#branch_target')!.textContent;
        if (newTargetBranch !== oldTargetBranch) {
          const resp = await POST(prTargetUpdateUrl, {data: new URLSearchParams({target_branch: String(newTargetBranch)})});
          if (!resp.ok) {
            throw new Error(`Failed to update PR target branch: ${resp.statusText}`);
          }
        }
      }
      ignoreAreYouSure(issueTitleEditor);
      window.location.reload();
    } catch (error) {
      console.error(error);
      showErrorToast(errorMessage(error));
    }
  });
}

export function initRepoIssueBranchSelect() {
  document.querySelector<HTMLElement>('#branch-select')?.addEventListener('click', (e: Event) => {
    const el = (e.target as HTMLElement).closest('.item[data-branch]');
    if (!el) return;
    const pullTargetBranch = document.querySelector('#pull-target-branch')!;
    const baseName = pullTargetBranch.getAttribute('data-basename');

View on GitHub (pinned to 43ace7cc8a)

Solutions

  1. Verify the chosen target branch still exists in the base repository (git ls-remote / branch dropdown) and retry
  2. Refresh the PR page and re-apply the edit — the title may have saved already, only the branch change needs redoing
  3. Confirm the PR is still open and the account has permission to change it
  4. Check server logs if the branch demonstrably exists and it still fails

Example fix

// before
const resp = await POST(prTargetUpdateUrl, {data: new URLSearchParams({target_branch: String(newTargetBranch)})});
if (!resp.ok) {
  throw new Error(`Failed to update PR target branch: ${resp.statusText}`);
}

// after (report status code plus server-provided message)
const resp = await POST(prTargetUpdateUrl, {data: new URLSearchParams({target_branch: String(newTargetBranch)})});
if (!resp.ok) {
  const body = await resp.json().catch(() => null);
  throw new Error(`Failed to update PR target branch: ${resp.status} ${body?.errorMessage ?? resp.statusText}`);
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Confirm the branch exists before offering it as a target
const branchExists = async (baseRepoBranchesUrl: string, branch: string) => {
  const resp = await GET(branchListUrl);
  if (!resp.ok) return false;
  const list = await resp.json();
  return list.some((b: {name: string}) => b.name === branch);
};

Try / catch

try {
  if (newTargetBranch !== oldTargetBranch) {
    const resp = await POST(prTargetUpdateUrl, {data: new URLSearchParams({target_branch: String(newTargetBranch)})});
    if (!resp.ok) throw new Error(`Failed to update PR target branch: ${resp.statusText}`);
  }
} catch (error) {
  // shipped pattern: toast the error; remember the title update earlier in the handler may have succeeded,
  // so on retry check the title before re-sending it
  showErrorToast(errorMessage(error));
}

Prevention

When it happens

Trigger: POST to the PR target-branch endpoint returns non-ok: the new target branch does not exist in the base repo (400/404, most common), the user lacks permission to edit the PR (403), the PR is already merged/closed and locked (403/422), or a merge-conflict state the server refuses (500).

Common situations: Renaming/deleting the target branch in the base repo while the PR edit dialog was open, then saving; branch names that differ only in case on case-insensitive filesystems; picked a branch from the dropdown that was force-pushed away; editing a merged PR (the #pull-desc-editor usually is absent there, but race windows exist).

Related errors


AI-assisted analysis of go-gitea/gitea@43ace7cc8a (2026-08-15). Data as JSON: /api/errors/4467d5da745847cc. Report an issue: GitHub.