Skip to content

[q] Fix image URLs using owner/repo placeholder instead of actual repository#2915

Merged
pelikhan merged 1 commit intomainfrom
fix/image-url-repository-b51d6dabebd78f83
Oct 31, 2025
Merged

[q] Fix image URLs using owner/repo placeholder instead of actual repository#2915
pelikhan merged 1 commit intomainfrom
fix/image-url-repository-b51d6dabebd78f83

Conversation

@github-actions
Copy link
Contributor

Q Workflow Optimization Report

Issue Found (from investigation)

Safe Outputs MCP Server - Image URL Generation

Problem Identified

Image URLs generated by the safe outputs MCP server for uploaded assets were using "owner/repo" as a placeholder instead of the actual repository "githubnext/gh-aw".

Root Cause:
The safe outputs MCP server code correctly falls back to "owner/repo" when GITHUB_REPOSITORY environment variable is not set:

const githubServer = process.env.GITHUB_SERVER_URL || "https://github.com";
const repo = process.env.GITHUB_REPOSITORY || "owner/repo";
const url = `${githubServer.replace("github.com", "raw.githubusercontent.com")}/${repo}/${normalizedBranchName}/${targetFileName}`;

However, the MCP server environment configuration in renderSafeOutputsMCPConfigWithOptions (pkg/workflow/mcp-config.go) was not passing through these standard GitHub Actions environment variables.

Variables Missing from MCP Environment:

  • GITHUB_REPOSITORY - The repository in "owner/repo" format
  • GITHUB_SERVER_URL - The GitHub server URL (defaults to https://github.com)

Changes Made

Modified File: pkg/workflow/mcp-config.go

Change 1: Added environment variables to renderSafeOutputsMCPConfigWithOptions (lines 107-124)

Added GITHUB_REPOSITORY and GITHUB_SERVER_URL to the MCP server environment configuration:

For Copilot (with passthrough syntax):

"GITHUB_REPOSITORY": "\\${GITHUB_REPOSITORY}",
"GITHUB_SERVER_URL": "\\${GITHUB_SERVER_URL}"

For Claude/Custom (direct env var reference):

"GITHUB_REPOSITORY": "$GITHUB_REPOSITORY",
"GITHUB_SERVER_URL": "$GITHUB_SERVER_URL"

Change 2: Added environment variables to TOML format (line 215)

Updated renderSafeOutputsMCPConfigTOML for Codex engine:

"GITHUB_REPOSITORY" = "${{ github.repository }}",
"GITHUB_SERVER_URL" = "${{ github.server_url }}"

Expected Improvements

Fixed Placeholder URLs: Image URLs will correctly use the actual repository instead of "owner/repo" placeholder
Valid Content Links: URLs will point to valid raw GitHub content locations
No Breaking Changes: These are standard GitHub Actions environment variables automatically available in all workflows
Cross-Engine Support: Fix applies to all engines (Copilot, Claude/Custom, and Codex)

Technical Details

Why This Fix Works:

  1. GITHUB_REPOSITORY and GITHUB_SERVER_URL are standard GitHub Actions environment variables
  2. They are automatically available in all workflow runs
  3. The MCP server passthrough syntax (\\${VAR} for Copilot, $VAR for Claude) correctly references these from the shell environment
  4. No explicit env setup needed in execution steps - variables are already present

Testing Strategy:

  • The fix will be validated by CI/CD pipeline
  • Integration tests will verify MCP config generation
  • Workflows using upload_assets safe output will test URL generation

References

  • Investigation Log: /tmp/gh-aw/cache-memory/q-image-url-investigation.md
  • Safe Outputs MCP Server: pkg/workflow/js/safe_outputs_mcp_server.cjs
  • MCP Config Rendering: pkg/workflow/mcp-config.go
  • GitHub Actions Environment Variables: Official Documentation

Related Issue: #2913

AI generated by Q

… server

The safe outputs MCP server generates URLs for uploaded assets using
GITHUB_REPOSITORY and GITHUB_SERVER_URL environment variables. However,
these standard GitHub Actions environment variables were not being passed
through to the MCP server environment, causing URLs to use the fallback
placeholder 'owner/repo' instead of the actual repository.

This fix adds GITHUB_REPOSITORY and GITHUB_SERVER_URL to the MCP server
environment configuration in renderSafeOutputsMCPConfigWithOptions for
all engines (Copilot, Claude/Custom, and Codex).

Changes:
- Added GITHUB_REPOSITORY passthrough in JSON format (Copilot/Claude)
- Added GITHUB_SERVER_URL passthrough in JSON format (Copilot/Claude)
- Added both variables to TOML format (Codex)

Impact:
- Image URLs will now correctly reference the actual repository
- URLs will point to valid raw GitHub content locations
- No breaking changes - these are standard GitHub Actions vars

Fixes: githubnext/gh-aw#2913
@pelikhan pelikhan merged commit 695e45d into main Oct 31, 2025
4 checks passed
@pelikhan pelikhan deleted the fix/image-url-repository-b51d6dabebd78f83 branch October 31, 2025 23:41
@github-actions
Copy link
Contributor Author

github-actions bot commented Nov 1, 2025

🔍 Smoke Test Investigation - Run #18988214642

Summary

The Smoke Codex workflow is failing with a TOML parse error caused by JSON-escaped quotes in the MCP configuration. This is a known recurring pattern (CODEX_TOML_JSON_ESCAPING) that has affected multiple runs.

Failure Details

  • Run: #18988214642
  • Commit: 695e45d (merge commit from this PR)
  • Trigger: schedule
  • Duration: 55.0s
  • Failed Job: agent (23s duration)

Root Cause Analysis

Primary Error (line 1007 in smoke-codex.lock.yml):

env = { "GH_AW_SAFE_OUTPUTS" = "/tmp/gh-aw/safeoutputs/outputs.jsonl", "GH_AW_SAFE_OUTPUTS_CONFIG" = "{\"create_issue\":{\"max\":1},\"missing_tool\":{}}", "GH_AW_ASSETS_BRANCH" = "", "GH_AW_ASSETS_MAX_SIZE_KB" = "", "GH_AW_ASSETS_ALLOWED_EXTS" = "" }
                                                                                                            ^
missing comma between key-value pairs, expected `,`

The Problem: When toJSON(env.GH_AW_SAFE_OUTPUTS_CONFIG) is substituted into the TOML inline table, it creates:

  • Input: ${{ toJSON(env.GH_AW_SAFE_OUTPUTS_CONFIG) }}
  • Expands to: "{\"create_issue\":{\"max\":1},\"missing_tool\":{}}"
  • Result in TOML: "GH_AW_SAFE_OUTPUTS_CONFIG" = "{\"create_issue\":{\"max\":1},\"missing_tool\":{}}"

The outer quotes from the TOML value + inner escaped quotes from JSON = invalid TOML syntax. The TOML parser sees conflicting quotes and fails at column 109.

Investigation Findings

This is a KNOWN PATTERN: From cache /tmp/gh-aw/cache-memory/investigations/SUMMARY-codex-toml-json-escaping.md:

Pattern: CODEX_TOML_JSON_ESCAPING

Root Cause:
TOML inline table syntax + JSON string values + shell substitution = 
Quote escaping complexity that creates invalid TOML syntax.

Occurrences:
- Run 18975512058 (2025-10-31 (redacted)) - toJSON() double-escaping
- Run 18977321431 (2025-10-31 (redacted)) - Shell variable double-quoting
- Run 18988214642 (2025-11-01 (redacted)) - THIS FAILURE

Why This Happens After This PR:
This PR (commit 695e45d) added GITHUB_REPOSITORY and GITHUB_SERVER_URL to the safe outputs MCP config environment. While that change itself is correct, it triggers the underlying TOML escaping issue that exists in how Codex MCP configs are generated.

The workflow compiler generates TOML inline tables with GitHub Actions expressions like ${{ toJSON(...) }}, which creates the quote escaping problem.

Failed Jobs and Errors

  1. pre_activation - succeeded (5s)
  2. activation - succeeded (4s)
  3. agent - failed (23s) - TOML parse error before Codex could start
  4. ⏭️ detection - skipped
  5. ⏭️ missing_tool - skipped
  6. ⏭️ create_issue - skipped

Error Location: `/tmp/gh-aw/agent-stdio.(redacted)

Error: TOML parse error at line 30, column 109
   |
30 | env = { "GH_AW_SAFE_OUTPUTS" = "/tmp/gh-aw/safeoutputs/outputs.jsonl", "GH_AW_SAFE_OUTPUTS_CONFIG" = "{\"create_issue\":{\"max\":1},\"missing_tool\":{}}", ...
   |                                                                                                             ^
missing comma between key-value pairs, expected `,`

Recommended Actions

Critical Priority - Permanent Fix

  • Use file-based TOML configuration instead of inline shell variable substitution
    • Write MCP config to /tmp/gh-aw/mcp-config/config.toml in a setup step
    • Reference the file in codex CLI: codex --config /tmp/gh-aw/mcp-config/config.toml
    • This matches the pattern used by Claude and GenAIScript engines
    • Files to modify:
      • pkg/workflow/mcp-config.go - Add renderCodexMCPConfigFile() function
      • pkg/workflow/codex_engine.go - Update to write and reference config file

Alternative Workaround (if file-based not feasible immediately):

  • Use base64 encoding for JSON values in TOML env vars
  • Or use separate TOML table syntax instead of inline tables

Prevention Strategies

  1. File-Based Configs: Move all engines to file-based MCP configs to avoid escaping issues
  2. Integration Tests: Add tests that parse generated TOML with actual TOML parser
  3. JSON in TOML Tests: Test cases specifically for JSON-valued environment variables
  4. Smoke Test Improvements: Make smoke tests block merges if they fail

Historical Context

This pattern was previously documented and posted to PR #2871 (Fix template injection vulnerabilities). The security fix in that PR moved from GitHub expressions to shell variables, which uncovered this TOML escaping issue.

Related Issues/PRs:

Technical Details

Current Generated TOML (broken):

[mcp_servers.safeoutputs]
command = "node"
args = ["/tmp/gh-aw/safeoutputs/mcp-server.cjs"]
env = { "GH_AW_SAFE_OUTPUTS" = "/tmp/gh-aw/safeoutputs/outputs.jsonl", "GH_AW_SAFE_OUTPUTS_CONFIG" = "{\"create_issue\":{\"max\":1},\"missing_tool\":{}}", ... }

Proposed File-Based Approach (fix):

# Setup step writes config file
- name: Write MCP Config
  run: |
    cat > /tmp/gh-aw/mcp-config/config.toml << 'EOF'
    [mcp_servers.safeoutputs]
    command = "node"
    args = ["/tmp/gh-aw/safeoutputs/mcp-server.cjs"]
    
    [mcp_servers.safeoutputs.env]
    GH_AW_SAFE_OUTPUTS = "/tmp/gh-aw/safeoutputs/outputs.jsonl"
    GH_AW_SAFE_OUTPUTS_CONFIG = '{"create_issue":{"max":1},"missing_tool":{}}'
    EOF

# Agent step references file
- name: Run Codex
  run: codex --config /tmp/gh-aw/mcp-config/config.toml ...

Investigation Pattern ID: CODEX_TOML_JSON_ESCAPING
Severity: Critical (blocks smoke tests)
Is Flaky: No (deterministic failure)
Investigation Stored: /tmp/gh-aw/cache-memory/investigations/2025-11-01-18988214642.json

Status: ⏳ Awaiting permanent fix implementation (file-based config approach)

AI generated by Smoke Detector - Smoke Test Failure Investigator

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant