openai / openai/codex-action

Codex output containing GitHub workflow commands can fail an otherwise successful action

Open
#175 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
1.2k
Forks
170
PR merge metrics
No merged PRs in 30d

Description

Summary

When Codex runs through the GitHub Action, text printed during execution can be interpreted as GitHub Actions workflow commands rather than ordinary log output.

This can happen when Codex reads source code containing command syntax such as ##[add-matcher]. The runner attempts to execute the embedded command, potentially marking the step as failed even if Codex itself completes successfully.

This does not require malicious input or an intentional instruction from the model. Simply inspecting a file containing GitHub Actions command syntax can trigger it.

Generic reproduction

The following workflow reproduces the underlying runner behavior without requiring Codex or an API key. It prints source text equivalent to what Codex might emit while inspecting a repository.

name: Reproduce command parsing in logs

on:
  workflow_dispatch:

jobs:
  reproduction:
    runs-on: ubuntu-latest
    steps:
      - name: Disable workflow commands in an earlier step
        run: echo "::stop-commands::repro-$(date +%s)-$RANDOM"

      - name: Print source code containing command syntax
        id: print_source
        continue-on-error: true
        run: |
          cat <<'EOF'
          core.info(`##[add-matcher]${matcherPath}`);
          EOF

      - name: Check the result
        run: |
          echo "Step outcome: ${{ steps.print_source.outcome }}"
          test "${{ steps.print_source.outcome }}" = "failure"

  control:
    runs-on: ubuntu-latest
    steps:
      - name: Suppress commands within the step that prints the text
        run: |
          token="repro-$(date +%s)-$RANDOM"
          echo "::stop-commands::$token"
          cat <<'EOF'
          core.info(`##[add-matcher]${matcherPath}`);
          EOF
          echo "::${token}::"

In the reproduction job, the runner interprets ##[add-matcher] inside the printed source text and attempts to load the remaining literal text as a matcher filename. That fails and marks the printing step as failed.

The earlier stop-commands step does not prevent this because suppression does not carry across step boundaries. The control places suppression and output in the same step.

Expected behavior

Codex’s model output and tool output should be treated as log data, not as instructions to the GitHub runner.

A successful Codex invocation should remain successful when it prints source code containing workflow-command syntax. Genuine process failures should still propagate normally.

Actual behavior

Command-like text in Codex’s stdout or stderr can affect the workflow. In particular, a malformed or nonexistent matcher path can fail the step independently of Codex’s exit status.

Downstream steps that require success may consequently be skipped, even when Codex has already produced its final result.

Suggested approach

Protect the output boundary within the action itself, rather than requiring callers to add a preceding suppression step.

One approach is to capture Codex’s stdout/stderr and neutralize workflow-command syntax before forwarding the logs. This should handle:

  • Legacy ##[command] syntax embedded anywhere in a line.
  • Leading ::command:: syntax.
  • Command sequences split across stream chunks.
  • Newline and carriage-return boundaries.
  • Both stdout and stderr.

The protection should preserve readable logs, leave the final result unchanged, and retain normal exit-status handling.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by locating where the action forwards Codex stdout and stderr, then run the generic workflow reproduction to observe GitHub Actions command parsing. Check handling of stream chunks and line boundaries against the listed legacy and leading command forms. Done means command-like output remains readable and harmless while genuine process failures still propagate.

Written by the indexing model from the issue text.

Assessment

Tech stack
github-actions, typescript
Domain
ci-cd
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.