Skip to content

Fix PR review workflow condition to avoid undefined property access#2157

Closed
neubig wants to merge 1 commit intomainfrom
fix/pr-review-workflow-condition
Closed

Fix PR review workflow condition to avoid undefined property access#2157
neubig wants to merge 1 commit intomainfrom
fix/pr-review-workflow-condition

Conversation

@neubig
Copy link
Contributor

@neubig neubig commented Feb 20, 2026

Summary

Fixes the PR review workflow which has been skipping 94% of runs since the security hardening change on Feb 20.

Problem

Since commit 795e20d (Clinejection hardening), only 2 out of 32 workflow runs succeeded - both from the opened event on non-draft PRs. All other triggers (ready_for_review, labeled, review_requested) were being skipped.

Root Cause

The condition structure evaluated properties like github.event.label.name and github.event.requested_reviewer.login even when those event types weren't triggered. GitHub Actions expressions may not properly short-circuit when accessing properties on undefined objects, causing the entire condition to fail.

Before (broken):

(author_association check) &&
(
    (opened && !draft) ||
    ready_for_review ||
    (labeled && label.name == 'review-this') ||   # ← label undefined for non-label events
    (review_requested && reviewer.login == '...')  # ← reviewer undefined for non-review events
)

Solution

Restructure the condition to isolate each trigger type, ensuring event-specific properties are only accessed when that event type is active:

(
    (
        (opened && !draft) || ready_for_review || (review_requested && reviewer.login == '...')
    ) && author_association check
) ||
(labeled && label.name == 'review-this')  # ← label only accessed when action == 'labeled'

This matches the working pattern used in OpenHands/OpenHands.

Testing

After this PR merges, triggering any of these should work:

  • ready_for_review - convert draft PR to ready
  • labeled - add review-this label
  • review_requested - request review from openhands-agent or all-hands-bot

Related

This fix only applies to software-agent-sdk. Other repos (runtime-api, deploy) use an older condition format that doesn't have this issue.

@neubig can click here to continue refining the PR


Agent Server images for this PR

GHCR package: https://github.com/OpenHands/agent-sdk/pkgs/container/agent-server

Variants & Base Images

Variant Architectures Base Image Docs / Tags
java amd64, arm64 eclipse-temurin:17-jdk Link
python amd64, arm64 nikolaik/python-nodejs:python3.12-nodejs22 Link
golang amd64, arm64 golang:1.21-bookworm Link

Pull (multi-arch manifest)

# Each variant is a multi-arch manifest supporting both amd64 and arm64
docker pull ghcr.io/openhands/agent-server:27e4f6f-python

Run

docker run -it --rm \
  -p 8000:8000 \
  --name agent-server-27e4f6f-python \
  ghcr.io/openhands/agent-server:27e4f6f-python

All tags pushed for this build

ghcr.io/openhands/agent-server:27e4f6f-golang-amd64
ghcr.io/openhands/agent-server:27e4f6f-golang_tag_1.21-bookworm-amd64
ghcr.io/openhands/agent-server:27e4f6f-golang-arm64
ghcr.io/openhands/agent-server:27e4f6f-golang_tag_1.21-bookworm-arm64
ghcr.io/openhands/agent-server:27e4f6f-java-amd64
ghcr.io/openhands/agent-server:27e4f6f-eclipse-temurin_tag_17-jdk-amd64
ghcr.io/openhands/agent-server:27e4f6f-java-arm64
ghcr.io/openhands/agent-server:27e4f6f-eclipse-temurin_tag_17-jdk-arm64
ghcr.io/openhands/agent-server:27e4f6f-python-amd64
ghcr.io/openhands/agent-server:27e4f6f-nikolaik_s_python-nodejs_tag_python3.12-nodejs22-amd64
ghcr.io/openhands/agent-server:27e4f6f-python-arm64
ghcr.io/openhands/agent-server:27e4f6f-nikolaik_s_python-nodejs_tag_python3.12-nodejs22-arm64
ghcr.io/openhands/agent-server:27e4f6f-golang
ghcr.io/openhands/agent-server:27e4f6f-java
ghcr.io/openhands/agent-server:27e4f6f-python

About Multi-Architecture Support

  • Each variant tag (e.g., 27e4f6f-python) is a multi-arch manifest supporting both amd64 and arm64
  • Docker automatically pulls the correct architecture for your platform
  • Individual architecture tags (e.g., 27e4f6f-python-amd64) are also available if needed

The previous condition structure could fail when evaluating properties like
github.event.label.name or github.event.requested_reviewer.login, even when
those branches of the OR expression should be short-circuited.

This restructures the condition to:
1. Group non-label triggers (opened, ready_for_review, review_requested)
   together with the author_association check
2. Isolate the label trigger separately so github.event.label is only
   accessed when action == 'labeled'

This matches the working pattern used in OpenHands/OpenHands.

Co-authored-by: openhands <openhands@all-hands.dev>
Copy link
Collaborator

@enyst enyst left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I didn't mean it, but it's funny! I suspect with reasonable -ish confidence that the reason for the failures may be this:

Image

I set the workflow under condition that the author is collaborator or member or owner.

But the workflow doesn't seem able to retrieve 'member' or 'owner', because the org doesn't provide that data? 😅

Result: AH folks are not recognized, while my account is still acceptable ("collaborator"):

@neubig
Copy link
Contributor Author

neubig commented Feb 21, 2026

Closing in favor of @enyst 's correct solution

@neubig neubig closed this Feb 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants