Skip to content

[safeoutputs] Improve upload_artifact path Description to Prevent Shell Variable Confusion #26521

Description

@github-actions

Summary

Analysis of the last 24 hours of workflow runs (150 runs) identified 1 error where an agent incorrectly used the upload_artifact safe output tool. The workflow prompt for the affected run appears correctly written, indicating the tool description needs improvement to prevent this class of error.

🔍 Error Analysis Details

Error Pattern: Agent Uses Literal $RUNNER_TEMP in Path

Occurrences: 1 time (workflow: Daily Project Performance Summary Generator (Using MCP Scripts))

What the agent did wrong:

Provided $RUNNER_TEMP/gh-aw/safeoutputs/upload-artifacts/activity_overview.png as the path value — a shell variable reference that is never expanded when it appears in a JSON string.

Actual safe output emitted (Run §24483658715):

{"integrity":"high","path":"$RUNNER_TEMP/gh-aw/safeoutputs/upload-artifacts/activity_overview.png","secrecy":"public","temporary_id":"aw_act1","type":"upload_artifact"}
```

**Validation error**:
```
ERR_VALIDATION: upload_artifact: path does not exist in staging directory:
$RUNNER_TEMP/gh-aw/safeoutputs/upload-artifacts/activity_overview.png.
Available files: [activity_overview.png, resolution_metrics.png, velocity_metrics.png]

Expected (correct value):

{"path": "activity_overview.png", "type": "upload_artifact", "temporary_id": "aw_act1"}

How the error happened:

  1. The workflow prompt's Phase 4 instructed the agent to copy chart files to the staging directory:
    cp /tmp/gh-aw/python/charts/activity_overview.png $RUNNER_TEMP/gh-aw/safeoutputs/upload-artifacts/
  2. When the agent then called upload_artifact, it naturally combined the staging destination from step 1 with the filename — producing $RUNNER_TEMP/gh-aw/safeoutputs/upload-artifacts/activity_overview.png.
  3. But shell variables like $RUNNER_TEMP are never expanded inside JSON string values. The validator received this as a literal relative path, looked for a file named $RUNNER_TEMP/gh-aw/safeoutputs/upload-artifacts/activity_overview.png inside the staging directory, and failed.

Current Tool Description

Current path field description (pkg/workflow/js/safe_outputs_tools.json)
{
  "name": "upload_artifact",
  "description": "Upload files as a run-scoped GitHub Actions artifact. Files can be pre-staged in $RUNNER_TEMP/gh-aw/safeoutputs/upload-artifacts/ or referenced by their original path — files not already in the staging directory are automatically copied there before upload. Absolute paths and paths relative to the workspace are supported. ...",
  "inputSchema": {
    "properties": {
      "path": {
        "type": "string",
        "description": "Path to the file or directory to upload. Can be relative to $RUNNER_TEMP/gh-aw/safeoutputs/upload-artifacts/, an absolute path, or a path relative to the workspace. Files not already in the staging directory are automatically copied there. Required unless filters is provided."
      }
    }
  }
}

Root Cause Analysis

The tool description has two problems that lead agents to use $RUNNER_TEMP as a literal string in JSON:

  1. Misleading phrase: "Can be relative to $RUNNER_TEMP/gh-aw/safeoutputs/upload-artifacts/" — agents read this as "you may use $RUNNER_TEMP/gh-aw/safeoutputs/upload-artifacts/ as a path prefix", when the intent is "you may use just the filename, and it will resolve against the staging directory".

  2. No warning about shell variables: The description mentions $RUNNER_TEMP in the path field without clarifying that shell variable references are never expanded inside JSON string values. This is a common source of confusion across all AI engines.

Recommended Improvements

1. Update path field description

Current:

"Path to the file or directory to upload. Can be relative to $RUNNER_TEMP/gh-aw/safeoutputs/upload-artifacts/, an absolute path, or a path relative to the workspace. Files not already in the staging directory are automatically copied there. Required unless filters is provided."

Suggested:

"Path to the file or directory to upload. Three formats are accepted: (1) filename only (e.g., \"chart.png\") — resolved relative to the upload staging directory; use this when the file was already copied there. (2) absolute path (e.g., \"/tmp/gh-aw/charts/chart.png\") — the file is automatically copied from disk into the staging directory. (3) workspace-relative path (e.g., \"reports/summary.json\") — resolved from the workspace root. ⚠️ Do NOT use shell variable syntax like $RUNNER_TEMP/... — shell variables are not expanded inside JSON string values. Required unless filters is provided."

2. Update top-level description

Replace the sentence "Files can be pre-staged in $RUNNER_TEMP/gh-aw/safeoutputs/upload-artifacts/ or referenced by their original path" with something like:

"Files can be referenced by their original absolute path (auto-copied into the staging area) or by a short relative filename if already staged. Shell variable references like $RUNNER_TEMP must NOT appear in the path value — they are not expanded in JSON."

3. Add a concrete example

Consider adding an examples field or expanding the description with a side-by-side:

# File already in staging directory:
"path": "activity_overview.png"       ✅ correct
"path": "$RUNNER_TEMP/.../activity_overview.png"  ❌ wrong — $RUNNER_TEMP not expanded

# File at original path:
"path": "/tmp/gh-aw/python/charts/activity_overview.png"  ✅ auto-copied to staging

Affected Workflows

The following workflow had the error:

  • daily-project-performance-summary-generator-using-mcp-scripts — 1 error (all 3 upload_artifact calls failed with same pattern, max-uploads policy allowed only 1 attempt to be reported)

Implementation Checklist

  • Update path field description in pkg/workflow/js/safe_outputs_tools.json
  • Update top-level description of upload_artifact tool to remove $RUNNER_TEMP staging path reference
  • Run make build to rebuild binary
  • Run make recompile to update all compiled workflows
  • Run make test to ensure no regressions
  • Monitor daily-project-performance-summary-generator-using-mcp-scripts runs for 2–3 days to confirm error rate drops

References

  • Tool schema: pkg/workflow/js/safe_outputs_tools.json
  • Handler: actions/setup/js/upload_artifact.cjs (see resolveFiles function, lines 294–340)
  • MCP server loader: actions/setup/js/safe_outputs_tools_loader.cjs

Run IDs with errors: §24483658715

Generated by Daily Safe Output Tool Optimizer · ● 473.6K ·

  • expires on Apr 17, 2026, 11:57 PM UTC

Activity

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

Metadata

Metadata

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions