qodo: unbreak the config loader, and stop the gate blocking clean PRs - #2269
Conversation
Qodo has been rejecting .pr_agent.toml outright since #2268 merged: ❌ PR-Agent failed to apply 'local' repo settings Error message: Forbidden directive: preload PR-Agent parses the file with a hardened Dynaconf loader that refuses the directives able to execute code or read arbitrary files. Matching is on the bare token, so the dynamic linker's library-injection variable — named in two of the guidelines, as something contributors must not use — trips the check even though it is only prose inside a string. The result is worse than a broken rule: the whole local config is dropped and the agent reviews with its stock prompt, so every guideline has been silently inactive since the merge while the reviews still looked normal. Both guidelines now describe the mechanism instead of naming the variable and point at best_practices.md section 4.1, which states the rule in full. best_practices.md and pr_compliance_checklist.yaml are unaffected — they are not parsed by that loader and keep the literal name. A header comment records the constraint, worded so it does not name the variable either. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
❌ PR-Agent failed to apply 'local' repo settings The configuration file needs to be a valid TOML, please fix it. Error message: Configuration content: |
PR Summary by QodoQodo: avoid directive-token match that breaks .pr_agent.toml loading
AI Description
Diagram
High-Level Assessment
Files changed (1)
|
Code Review by Qodo
1. Gate won’t rerun on comment
|
The gate looked only for a review OBJECT by the bot. Qodo creates one when it has inline comments to hang on the diff, so every PR it finds something in has one — which is why this passed on #2268 and on every devourer PR checked. A clean PR gets no review object at all. On #2269 Qodo reported "Bugs (0), Rule violations (0), Requirement gaps (0)" as a plain issue comment and created nothing else, so the gate failed with "no Qodo review on this PR yet" and could never go green — the check blocked hardest precisely when there was nothing to fix. Accept either signal: a review object, or an issue comment headed "Code Review by Qodo". The header is matched specifically rather than "any comment by the bot", because Qodo also posts "Qodo is busy working" (a placeholder written before it has read anything), "PR Summary by Qodo" (/describe output), and the "failed to apply 'local' repo settings" error. Counting those would pass a PR the agent never reviewed. Verified against the live API: #2269 now 0 objects + 1 comment -> PASS, #2268 1 + 1 -> PASS, and the three noise comments are all rejected. Thread resolution is unaffected: a zero-finding PR opens no threads, so the unresolved count is 0 and the gate falls through to PASS. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
/review |
| commented=$(gh api "repos/$REPO_OWNER/$REPO_NAME/issues/$PR/comments" \ | ||
| --paginate --jq ".[] | ||
| | select(.user.login | startswith(\"$BOT\")) | ||
| | select(.body | test(\"Code Review by Qodo\"; \"i\")) |
There was a problem hiding this comment.
1. Gate won’t rerun on comment 🐞 Bug ☼ Reliability
qodo-gate now accepts a Qodo issue comment headed “Code Review by Qodo” as proof of review, but the workflow is not triggered by issue-comment creation/edit events. For clean PRs (no review object), the initial run will usually fail before Qodo posts that comment and won’t automatically rerun in response to it, so the required check can still block until a manual rerun or another unrelated trigger occurs.
Agent Prompt
## Issue description
The gate now treats a Qodo *issue comment* (“Code Review by Qodo”) as a valid completion signal, but the workflow is only triggered by PR/review/review-comment events. When Qodo’s only output is an issue comment (clean PR), the workflow often fails before Qodo posts it and will not rerun because the comment itself doesn’t trigger this workflow.
## Issue Context
- The workflow’s `on:` section does not include `issue_comment`, so posting the Qodo summary comment won’t schedule a new run.
- The new logic explicitly relies on that comment (`commented=... test("Code Review by Qodo")`) to pass clean PRs.
## Fix Focus Areas
Implement one of the following (prefer the polling option to avoid broad `issue_comment` triggers):
1) **Polling in the existing run (recommended):**
- Before failing on `reviewed==0 && commented==0`, sleep-and-retry for a bounded time (e.g., up to 5–10 minutes), re-querying reviews/comments each iteration.
- Only fail after the timeout if both signals are still absent.
2) **Alternative:** add an `issue_comment` trigger and ensure it cannot create a false PASS on non-Qodo comments.
### Code locations to modify
- .github/workflows/qodo-gate.yml[41-47]
- .github/workflows/qodo-gate.yml[86-131]
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
|
Code review by qodo was updated up to the latest commit e829edf |
Problem
Since #2268 merged, Qodo has been rejecting
.pr_agent.tomlon every PR (example):PR-Agent parses the repo-local config with a hardened Dynaconf loader that rejects directives capable of executing code or reading arbitrary files. It matches on the bare token — and the dynamic linker's library-injection environment variable, which two of the guidelines named as something contributors must not use, ends in one of those tokens. It tripped the check while being nothing but prose inside a string.
The irony is that the rule banning the thing is what broke the config.
This failure mode is nastier than a wrong rule. The agent does not fall back to a partial config — it drops the local settings entirely and reviews with its stock prompt. So every guideline added in #2268 has been inactive since it merged, while the reviews still looked perfectly normal. Nothing on the PR indicates the standards were skipped except that one comment.
Fix
Both guidelines now describe the mechanism and point at
best_practices.mdsection 4.1, which states the rule in full and is not affected:best_practices.mdandpr_compliance_checklist.yamlare untouched and keep the literal variable name — they are not parsed by that loader. The rule itself is unchanged in substance, and the agent still reaches the full wording through the standards file.A header comment records the constraint for whoever edits this next. It is worded so that it does not name the variable either — I checked the raw file has zero occurrences of any rejected token, comments included, since I could not confirm whether the scan ignores comments.
Evidence
No hardware involved; this is review configuration.
.pr_agent.tomlparses undertomllib, and the guidelines still carry the rule ('injection shims'and the section 4.1 cross-reference both present).This PR cannot test itself, and the failure comment on it is expected. PR-Agent reads the repo-local config from the default branch, not from the PR head — sensible, since otherwise a PR could inject config for its own review. Two observations pin this down:
14:20:10Z, comment14:20:14Z). Before the mergemasterhad no.pr_agent.toml, so there was nothing to reject.masterstill carries the old file. The fix on this branch is invisible to the loader.Note also that the bot renders an empty "Configuration content" block, consistent with rejecting the file before it can echo anything.
So the fix cannot be proven from here; it is verified by inspection (zero occurrences of any rejected token in the raw file, comments included). The real check is the first PR opened after this merges: if it draws a normal Qodo review with no "failed to apply 'local' repo settings" comment, the config is live. If the comment persists, the token match is broader than assumed and the remaining guidelines need the same treatment.
Second fix: qodo-gate blocked every clean PR
Found while trying to merge this PR — its own gate failed, and would have failed forever.
The gate looked only for a review object by the bot. Qodo creates one when it has inline comments to attach to the diff, so any PR it finds something in has one. That is why it passed on #2268 and on every OpenIPC/devourer PR I checked — all of them had findings.
A clean PR gets no review object at all. Qodo reported
Bugs (0), Rule violations (0), Requirement gaps (0)on this PR as a plain issue comment and created nothing else, so the gate reported "no Qodo review on this PR yet" and could never go green. The check blocked hardest exactly when there was nothing to fix.It now accepts either signal: a review object, or an issue comment headed
Code Review by Qodo. The header is matched specifically rather than "any comment by the bot", because Qodo also postsQodo is busy working(a placeholder written before it has read anything),PR Summary by Qodo(/describeoutput), and thefailed to apply 'local' repo settingserror. Counting those would pass a PR the agent never reviewed.Verified against the live API before pushing:
All three noise comments are correctly rejected. Thread resolution is unaffected: a zero-finding PR opens no threads, so the unresolved count is 0 and it falls through to PASS.
Unlike the config fix, this one is testable here —
pull_requestworkflows run from the merge commit, so this PR's ownqodo-gateused the fixed file and passed withreview found: 0 review object(s), 1 review comment(s).Scope
general/overlay/; no package sources changed🤖 Generated with Claude Code