Orphan deletion still occurs with empty branchPrefix (regression of #15733) and branchName deprecated (how to replace it with additionalBranchPrefix?) #43674
Replies: 2 comments 3 replies
-
|
Beta Was this translation helpful? Give feedback.
-
|
thanks for your feedback and yes, we indeed tried using the template syntax in the field branchPrefix first, but it didn't resolve the template and the last time I checked did not have the indicator
So you probably want to amend that section in the document to match the new info. I will certainly try again and if this works with branchPrefix, I will be happy to use this and report back (and mark your post as answered). kind regards, |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
How are you running Renovate?
None
Which platform you running Renovate on?
GitHub.com
Which version of Renovate are you using?
v41.159.4
Please tell us more about your question or problem
Context
Our organisation enforces the following branch naming convention via GitHub branch-protection rules:
All branches — including Renovate branches — must be prefixed with a version identifier derived from the base branch:
baseBranchmain/developmain/quality/renovate-maven-artifacts400XXXX/develop400XXXX/quality/renovate-maven-artifactsCurrent configuration (works, but uses deprecated
branchName){ "$schema": "https://docs.renovatebot.com/renovate-schema.json", "baseBranches": ["main/develop", "400XXXX/develop"], "branchPrefix": "", "additionalBranchPrefix": "", "branchName": "{{lookup (split baseBranch '/') 0 }}/quality/renovate-{{{branchTopic}}}" }The
{{lookup (split baseBranch '/') 0 }}helper extracts the first path segment frombaseBranch(e.g.
mainfrommain/develop,400XXXXfrom400XXXX/develop) and uses it as the branch prefix.This produces the correct branch names at runtime.
However, the documentation for
branchNamemarks this field as deprecated and recommends using
branchPrefix,additionalBranchPrefix, orbranchTopicinstead.Question 1 — How to replace the deprecated
branchName?The dynamic prefix needs to go somewhere in the non-deprecated fields.
Does
additionalBranchPrefixsupport the same template variables and helpers asbranchName?The documentation does not make this explicit. Would the following work?
{ "branchPrefix": "", "additionalBranchPrefix": "{{lookup (split baseBranch '/') 0 }}/quality/renovate-" }Or is there another recommended approach to achieve a baseBranch-derived prefix?
Question 2 / Bug — Orphan branch deletion with empty
branchPrefixRegardless of how the branch name is constructed, setting
branchPrefix: ""causes Renovate totreat every branch in the repository as a Renovate-managed branch. Branches that cannot be
matched to an active update are then marked as orphans and deleted.
We observed this in production (Renovate engine 41.x):
Relation to the prior fix
This is similar to Discussion #15732,
which was addressed by Issue #15733
and released in v32.83.3.
The
isModifiedcheck introduced by that fix does provide partial protection: branches withcommits from non-Renovate authors are skipped. However, the fix is incomplete when
branchPrefixis"":baseBranchitself is targeted without theisModifiedcheck being applied —when the branch cache is absent, deletion is attempted unconditionally.
non-Renovate author) remain at risk.
the repository being treated as a Renovate-managed branch — is not addressed.
Minimal reproduction
Confirmed against
renovatebot/github-action@v43.0.19(Renovate engine 41.x):👉 https://github.com/awrrl/test-renovate-del-orphan
Run 1 — first execution, no prior state:
Renovate correctly created
main/quality/renovate-org.apache.commons-commons-lang3-3.x,then immediately attempted to delete the
baseBranchas an orphan (noisModifiedcheckwas performed):
The branch was saved only because GitHub refuses to delete the default branch.
Run 2 — warm cache:
Feature branches were also identified as orphans. The
isModifiedcheck ran and foundcommits from non-Renovate authors, so deletion was skipped:
In our production repositories these same branches were deleted (the branches were clean
with respect to the
isModifiedheuristic), confirming that theisModifiedcheck is not asufficient safeguard.
Expected behavior
Renovate should identify orphan-branch candidates by matching branch names against the pattern
generated from
branchName(orbranchPrefix+additionalBranchPrefix+branchTopic).Branches whose names do not match the generated pattern must never be treated as
Renovate-managed, regardless of whether
branchPrefixis empty.Specifically:
baseBranchmust never be a candidate for orphan deletion.branchNametemplate must never be candidates fororphan deletion.
Logs (if relevant)
Logs
first run ``` 2026-05-29T09:09:21.1175613Z DEBUG: setCachedModifiedResult(): Branch cache not present (repository=awrrl/test-renovate-del-orphan) 2026-05-29T09:09:21.1177021Z INFO: Deleting orphan branch (repository=awrrl/test-renovate-del-orphan, branch=main/develop) 2026-05-29T09:09:22.0510412Z DEBUG: Git function thrown (repository=awrrl/test-renovate-del-orphan) 2026-05-29T09:09:22.0511336Z "err": { 2026-05-29T09:09:22.0511586Z "task": { 2026-05-29T09:09:22.0511990Z "commands": ["push", "--delete", "origin", "main/develop", "--no-verify"], 2026-05-29T09:09:22.0512653Z "format": "utf-8", 2026-05-29T09:09:22.0513146Z "parser": "[function]" 2026-05-29T09:09:22.0513632Z }, 2026-05-29T09:09:22.0515603Z "message": "To https://github.com/awrrl/test-renovate-del-orphan.git\n ! [remote rejected] main/develop (refusing to delete the current branch: refs/heads/main/develop)\nerror: failed to push some refs to 'https://github.com/awrrl/test-renovate-del-orphan.git'\n", 2026-05-29T09:09:22.0522467Z "stack": "Error: To https://**redacted**@3.29.0/node_modules/simple-git/src/lib/plugins/error-detection.plugin.ts:42:29)\n at PluginStore.exec (/usr/local/renovate/node_modules/.pnpm/simple-git@3.29.0/node_modules/simple-git/src/lib/plugins/plugin-store.ts:54:29)\n at /usr/local/renovate/node_modules/.pnpm/simple-git@3.29.0/node_modules/simple-git/src/lib/runners/git-executor-chain.ts:124:42\n at new Promise ()\n at GitExecutorChain.handleTaskData (/usr/local/renovate/node_modules/.pnpm/simple-git@3.29.0/node_modules/simple-git/src/lib/runners/git-executor-chain.ts:121:14)\n at GitExecutorChain.attemptRemoteTask (/usr/local/renovate/node_modules/.pnpm/simple-git@3.29.0/node_modules/simple-git/src/lib/runners/git-executor-chain.ts:97:40)\n at processTicksAndRejections (node:internal/process/task_queues:105:5)\n at GitExecutorChain.attemptTask (/usr/local/renovate/node_modules/.pnpm/simple-git@3.29.0/node_modules/simple-git/src/lib/runners/git-executor-chain.ts:61:18)" 2026-05-29T09:09:22.0527436Z } 2026-05-29T09:09:22.0528129Z DEBUG: No remote branch to delete with name: main/develop (repository=awrrl/test-renovate-del-orphan) 2026-05-29T09:09:22.0576278Z DEBUG: No local branch to delete with name: main/develop (repository=awrrl/test-renovate-del-orphan) ``` second run ``` 2026-05-29T09:16:13.0215855Z DEBUG: Orphan Branch is modified - skipping branch deletion (repository=awrrl/test-renovate-del-orphan, branch=main/feature/EXAMPLE-123) 2026-05-29T09:16:13.0216721Z DEBUG: findPr(main/multi-feature/HEPIC-12345, undefined, open) (repository=awrrl/test-renovate-del-orphan) 2026-05-29T09:16:13.0217426Z DEBUG: branch.isModified(): using git to calculate (repository=awrrl/test-renovate-del-orphan) 2026-05-29T09:16:13.0278952Z DEBUG: branch.isModified() = true (repository=awrrl/test-renovate-del-orphan) 2026-05-29T09:16:13.0280103Z "branchName": "main/multi-feature/HEPIC-12345", 2026-05-29T09:16:13.0280953Z "unrecognizedAuthors": ["Goetz.Lohmann@dedalus.com"] 2026-05-29T09:16:13.0282073Z DEBUG: setCachedModifiedResult(): Branch cache not present (repository=awrrl/test-renovate-del-orphan) 2026-05-29T09:16:13.0283591Z DEBUG: Orphan Branch is modified - skipping branch deletion (repository=awrrl/test-renovate-del-orphan, branch=main/multi-feature/HEPIC-12345) ```Beta Was this translation helpful? Give feedback.
All reactions