Skip to content

[safeoutputs] Clarify upload_artifact path semantics and enforce /tmp/gh-aw/... staging guidance#26533

Merged
pelikhan merged 4 commits intomainfrom
copilot/improve-upload-artifact-path-description
Apr 16, 2026
Merged

[safeoutputs] Clarify upload_artifact path semantics and enforce /tmp/gh-aw/... staging guidance#26533
pelikhan merged 4 commits intomainfrom
copilot/improve-upload-artifact-path-description

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 16, 2026

Recent safe-outputs failures showed agents passing shell-variable-style paths as literal JSON strings to upload_artifact, causing staging-path resolution errors. The schema text was ambiguous about relative paths and did not explicitly warn that shell variables are not expanded in JSON values.

  • Schema clarification for upload_artifact

    • Updated top-level tool description to remove misleading staging guidance tied to shell variables.
    • Clarified supported path modes: staged filename, absolute path (auto-copied), and workspace-relative path.
    • Explicitly guides staging-related references to /tmp/gh-aw/... paths.
  • path field hardening

    • Rewrote inputSchema.properties.path.description with explicit accepted formats.
    • Added an explicit warning that shell variable syntax (e.g. $VAR/...) is invalid in JSON string values.
    • Included a concrete correct vs incorrect example directly in the field description, using generic variable syntax instead of $RUNNER_TEMP.
  • Consistency update

    • Aligned wording (authorized) in the updated description text.
{
  "path": "activity_overview.png"
}
{
  "path": "$VAR/gh-aw/safeoutputs/upload-artifacts/activity_overview.png"
}

[!WARNING]

@github-actions
Copy link
Copy Markdown
Contributor

Hey @Copilot 👋 — thanks for tackling the upload_artifact path description confusion! Improving the schema description to prevent shell-variable expansion surprises is a solid documentation quality fix.

A few things to wrap up before this is ready for review:

  • No code changes yet — the PR is a WIP draft with an empty diff. The investigation checklist items are checked off, but the actual schema edits haven't been committed yet.
  • Key next steps:
    1. Commit the upload_artifact schema description edits (accepted path styles + $RUNNER_TEMP warning)
    2. Update upload_artifact.inputSchema.properties.path.description with explicit accepted formats and a non-expansion warning
    3. Run make build && make recompile && make agent-finish
    4. Add or update tests covering the new schema wording
  • PR description — once the implementation lands, consider replacing the task-list body with a proper description (root cause → what changed → how to verify) to help reviewers understand the change quickly.

Looking forward to seeing the implementation! 🚀

Generated by Contribution Check · ● 1.5M ·

Copilot AI changed the title [WIP] Improve upload_artifact path description to prevent shell variable confusion [safeoutputs] Clarify upload_artifact path semantics to prevent literal $RUNNER_TEMP misuse Apr 16, 2026
Copilot AI requested a review from pelikhan April 16, 2026 01:52
@pelikhan pelikhan marked this pull request as ready for review April 16, 2026 02:41
Copilot AI review requested due to automatic review settings April 16, 2026 02:41
@pelikhan
Copy link
Copy Markdown
Collaborator

@copilot NEVER suggest the user to use $RUNNER_TEMP! Always suggest using /tmp/gh-aw/... based paths. The upload-artifact staging folder SHOULD BE under /tmp/gh-aw/... NOT $RUNNER_TEMP

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Clarifies upload_artifact tool schema text to prevent agents from passing literal $RUNNER_TEMP/... strings as JSON path values, and to better describe supported path forms.

Changes:

  • Updated upload_artifact top-level description to remove ambiguous staging-path wording and warn that shell variables aren’t expanded in JSON.
  • Rewrote path field description with explicit accepted formats and correct vs incorrect examples.
  • Standardized wording to “authorized”.
Show a summary per file
File Description
pkg/workflow/js/safe_outputs_tools.json Updates the compiled workflow-side safe-outputs tool schema wording for upload_artifact path semantics.
actions/setup/js/safe_outputs_tools.json Updates the action/runtime-side safe-outputs tool schema wording for upload_artifact path semantics.

Copilot's findings

Tip

Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comments suppressed due to low confidence (2)

pkg/workflow/js/safe_outputs_tools.json:1599

  • This description says format (1) is “filename only” for staged files, but the upload_artifact handler accepts staged paths that include subdirectories (staging-root-relative), and relative paths are preserved when auto-copied from the workspace/cwd. Consider changing this to allow “relative path under the staging directory (e.g., "reports/chart.png")” rather than restricting to basename-only.
                    "description": "Path to the file or directory to upload. Three formats are accepted: (1) filename only (e.g., \"chart.png\") for files already in the upload staging directory; (2) absolute path (e.g., \"/tmp/gh-aw/charts/chart.png\") to auto-copy 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/...\" because shell variables are not expanded in JSON string values. Example: \"path\": \"activity_overview.png\" is correct for staged files, while \"path\": \"$RUNNER_TEMP/gh-aw/safeoutputs/upload-artifacts/activity_overview.png\" is invalid. Required unless filters is provided."

actions/setup/js/safe_outputs_tools.json:864

  • This says staged format (1) is “filename only”, but the implementation accepts relative paths with subdirectories under the staging directory (e.g., "reports/chart.png"), and relative paths are preserved when auto-copied from the workspace/cwd. Update wording to “staging-directory-relative path” instead of basename-only.
          "description": "Path to the file or directory to upload. Three formats are accepted: (1) filename only (e.g., \"chart.png\") for files already in the upload staging directory; (2) absolute path (e.g., \"/tmp/gh-aw/charts/chart.png\") to auto-copy 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/...\" because shell variables are not expanded in JSON string values. Example: \"path\": \"activity_overview.png\" is correct for staged files, while \"path\": \"$RUNNER_TEMP/gh-aw/safeoutputs/upload-artifacts/activity_overview.png\" is invalid. Required unless filters is provided."
  • Files reviewed: 2/2 changed files
  • Comments generated: 2

Comment thread pkg/workflow/js/safe_outputs_tools.json Outdated
{
"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. Returns a temporary artifact ID (aw_*) that can be resolved to a download URL by an authorised step. Retention and archive settings are fixed by workflow configuration. Exactly one of path or filters must be present.",
"description": "Upload files as a run-scoped GitHub Actions artifact. 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 because they are not expanded in JSON strings. Absolute paths and paths relative to the workspace are supported. Returns a temporary artifact ID (aw_*) that can be resolved to a download URL by an authorized step. Retention and archive settings are fixed by workflow configuration. Exactly one of path or filters must be present.",
Copy link

Copilot AI Apr 16, 2026

Choose a reason for hiding this comment

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

The tool description implies only a “short relative filename” is valid for already-staged content, but the handler actually accepts any path relative to the staging root (including subdirectories) and will also auto-copy workspace/cwd-relative paths when the staging-relative path is missing (see actions/setup/js/upload_artifact.cjs resolveFiles()). Reword this to “staging-dir-relative path” and mention workspace-relative paths here as well so it matches the implementation and the field-level description.

This issue also appears on line 1599 of the same file.

See below for a potential fix:

        "description": "Upload files as a run-scoped GitHub Actions artifact. Files can be referenced by their original absolute path (auto-copied into the staging area), by a staging-dir-relative path if already staged, or by a path relative to the workspace/cwd when the staging-relative path is not present. Shell variable references like $RUNNER_TEMP must NOT appear in the path value because they are not expanded in JSON strings. Absolute paths and workspace-relative paths are supported. Returns a temporary artifact ID (aw_*) that can be resolved to a download URL by an authorized step. Retention and archive settings are fixed by workflow configuration. Exactly one of path or filters must be present.",
        "inputSchema": {
            "type": "object",
            "properties": {
                "path": {
                    "type": "string",
                    "description": "Path to the file or directory to upload. Three formats are accepted: (1) staging-dir-relative path (e.g., \"chart.png\" or \"charts/chart.png\") for files already in the upload staging directory, including subdirectories; (2) absolute path (e.g., \"/tmp/gh-aw/charts/chart.png\") to auto-copy from disk into the staging directory; (3) workspace-relative path (e.g., \"reports/summary.json\") resolved from the workspace root and auto-copied if a matching staging-dir-relative path is not found. Do NOT use shell variable syntax like \"$RUNNER_TEMP/...\" because shell variables are not expanded in JSON string values. Example: \"path\": \"activity_overview.png\" is correct for staged files, while \"path\": \"$RUNNER_TEMP/gh-aw/safeoutputs/upload-artifacts/activity_overview.png\" is invalid. Required unless filters is provided."

Copilot uses AI. Check for mistakes.
{
"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. Returns a temporary artifact ID (aw_*) that can be resolved to a download URL by an authorised step. Retention and archive settings are fixed by workflow configuration. Exactly one of path or filters must be present.",
"description": "Upload files as a run-scoped GitHub Actions artifact. 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 because they are not expanded in JSON strings. Absolute paths and paths relative to the workspace are supported. Returns a temporary artifact ID (aw_*) that can be resolved to a download URL by an authorized step. Retention and archive settings are fixed by workflow configuration. Exactly one of path or filters must be present.",
Copy link

Copilot AI Apr 16, 2026

Choose a reason for hiding this comment

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

The tool description implies only a “short relative filename” is valid for already-staged content, but the handler accepts any staging-root-relative path (including subdirectories) and will auto-copy workspace/cwd-relative paths when the staging-relative path is missing (actions/setup/js/upload_artifact.cjs resolveFiles()). Reword this to “staging-dir-relative path” and mention workspace-relative paths here too for consistency with actual behavior.

This issue also appears on line 864 of the same file.

See below for a potential fix:

    "description": "Upload files as a run-scoped GitHub Actions artifact. Files can be referenced by their original absolute path (auto-copied into the staging area), by a staging-dir-relative path if already staged, or by a path relative to the workspace (auto-copied into the staging area). Shell variable references like $RUNNER_TEMP must NOT appear in the path value because they are not expanded in JSON strings. Absolute paths and paths relative to the workspace are supported. Returns a temporary artifact ID (aw_*) that can be resolved to a download URL by an authorized step. Retention and archive settings are fixed by workflow configuration. Exactly one of path or filters must be present.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "path": {
          "type": "string",
          "description": "Path to the file or directory to upload. Three formats are accepted: (1) staging-dir-relative path (e.g., \"charts/chart.png\" or \"chart.png\") for files already in the upload staging directory; (2) absolute path (e.g., \"/tmp/gh-aw/charts/chart.png\") to auto-copy from disk into the staging directory; (3) workspace-relative path (e.g., \"reports/summary.json\") resolved from the workspace root and auto-copied into the staging directory. Do NOT use shell variable syntax like \"$RUNNER_TEMP/...\" because shell variables are not expanded in JSON string values. Example: \"path\": \"activity_overview.png\" is correct for a staged file, while \"path\": \"$RUNNER_TEMP/gh-aw/safeoutputs/upload-artifacts/activity_overview.png\" is invalid. Required unless filters is provided."

Copilot uses AI. Check for mistakes.
@github-actions github-actions Bot mentioned this pull request Apr 16, 2026
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Apr 16, 2026

@copilot NEVER suggest the user to use $RUNNER_TEMP! Always suggest using /tmp/gh-aw/... based paths. The upload-artifact staging folder SHOULD BE under /tmp/gh-aw/... NOT $RUNNER_TEMP

Updated in a2c028f. I removed $RUNNER_TEMP references from both upload_artifact descriptions and now guide staging paths under /tmp/gh-aw/..., while keeping a generic shell-variable non-expansion warning ($VAR/...).

Copilot AI changed the title [safeoutputs] Clarify upload_artifact path semantics to prevent literal $RUNNER_TEMP misuse [safeoutputs] Clarify upload_artifact path semantics and enforce /tmp/gh-aw/... staging guidance Apr 16, 2026
{
"name": "upload_artifact",
"description": "Upload files as a run-scoped GitHub Actions artifact. 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 because they are not expanded in JSON strings. Absolute paths and paths relative to the workspace are supported. Returns a temporary artifact ID (aw_*) that can be resolved to a download URL by an authorized step. Retention and archive settings are fixed by workflow configuration. Exactly one of path or filters must be present.",
"description": "Upload files as a run-scoped GitHub Actions artifact. Files can be referenced by their original absolute path (auto-copied into the staging area under /tmp/gh-aw/safeoutputs/upload-artifacts/) or by a short relative filename if already staged. Use /tmp/gh-aw/... paths for staging-related references. Shell variable syntax (for example, \"$VAR/...\") must NOT appear in path values because variables are not expanded in JSON strings. Absolute paths and paths relative to the workspace are supported. Returns a temporary artifact ID (aw_*) that can be resolved to a download URL by an authorized step. Retention and archive settings are fixed by workflow configuration. Exactly one of path or filters must be present.",
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

@copilot remove "Use /tmp/gh-aw/... paths for staging-related references."

@pelikhan pelikhan merged commit 6f6d2d9 into main Apr 16, 2026
42 checks passed
@pelikhan pelikhan deleted the copilot/improve-upload-artifact-path-description branch April 16, 2026 03:13
Copilot stopped work on behalf of pelikhan due to an error April 16, 2026 03:23
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.

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

3 participants