Summary
With safe-outputs.upload-artifact configured, the upload_artifact tool returns
{"result":"success"} and records an item, but no safe-outputs-upload-artifacts artifact is
produced, so the file never reaches the safe_outputs job or any custom safe-output job
downstream. The run succeeds throughout.
The silent part is what makes this worth reporting: a workflow that uses upload-artifact to move a
generated file to a privileged job cannot tell that the file was lost, because every signal it has
says the upload worked.
Version: gh aw v0.88.7, engine copilot/auto/v1.0.80, ubuntu-latest.
Configuration
safe-outputs:
upload-artifact:
allowed-paths: ["*.md", "**/*.md"]
jobs:
publish-plan:
runs-on: ubuntu-latest
needs: safe_outputs
max: 1
inputs:
artifact_filename:
description: "File name of the uploaded file"
required: true
type: string
steps:
- uses: actions/download-artifact@v8
continue-on-error: true
with:
name: safe-outputs-upload-artifacts
path: /tmp/staging
- run: find /tmp/staging -type f || echo "ABSENT"
The prompt instructs the agent to write a file of roughly 25,000 characters, upload it, and then
call the custom job with the file name.
What happens
Two variants were run.
1. File written next to the agent's working directory.
cd /tmp/gh-aw/agent && printf '{"path":"plan.md"}' | safeoutputs upload_artifact .
→ Upload succeeded.
Recorded item: {"path":"plan.md","type":"upload_artifact"}. No artifact produced.
2. File written into the staging directory the tool's own schema names, verified present at
25,768 bytes before and after the call.
printf '{"path":"plan.md","integrity":"high","secrecy":"public"}' | safeoutputs upload_artifact .
→ {"result":"success"}
Again no artifact produced. The agent independently confirmed the staged file was still there at
full size after the call.
In both runs:
- the run listing contains
activation, agent, detection, safe-outputs-items,
agent-output-fallback, usage, aic-usage-cache — and no safe-outputs-upload-artifacts;
- the
safe_outputs job's Download upload-artifact staging step runs and finds nothing;
- the downstream custom job's
download-artifact for safe-outputs-upload-artifacts fails;
publish_plan, safe_outputs, and the run as a whole all report success.
Expected
Either the staged file is uploaded as safe-outputs-upload-artifacts, or upload_artifact returns
an error the agent can act on. Returning success for an upload that did not happen means a workflow
built on this transport silently produces references to files that do not exist.
Possible cause
The agent container is given both /tmp/gh-aw and
${RUNNER_TEMP}/gh-aw/safeoutputs/upload-artifacts as mounts. The tool schema served to the agent
names a staging directory under /tmp/gh-aw, while safe_outputs downloads into
${RUNNER_TEMP}/gh-aw/safeoutputs/upload-artifacts/. If those are genuinely different directories,
a file written to the advertised path would never be collected — which matches the observed
behaviour.
This may well be a misconfiguration on my side rather than a defect. If so, the request stands in a
smaller form: the failure should not be silent.
Note on --help
safeoutputs upload_artifact --help is truncated with an ellipsis and does not show the accepted
path formats. The full schema is only visible in
${RUNNER_TEMP}/gh-aw/mcp-cli/tools/safeoutputs.json. An agent that reads only the help text is
unlikely to use the tool correctly.
Summary
With
safe-outputs.upload-artifactconfigured, theupload_artifacttool returns{"result":"success"}and records an item, but nosafe-outputs-upload-artifactsartifact isproduced, so the file never reaches the
safe_outputsjob or any custom safe-output jobdownstream. The run succeeds throughout.
The silent part is what makes this worth reporting: a workflow that uses
upload-artifactto move agenerated file to a privileged job cannot tell that the file was lost, because every signal it has
says the upload worked.
Version:
gh awv0.88.7, enginecopilot/auto/v1.0.80,ubuntu-latest.Configuration
The prompt instructs the agent to write a file of roughly 25,000 characters, upload it, and then
call the custom job with the file name.
What happens
Two variants were run.
1. File written next to the agent's working directory.
Recorded item:
{"path":"plan.md","type":"upload_artifact"}. No artifact produced.2. File written into the staging directory the tool's own schema names, verified present at
25,768 bytes before and after the call.
Again no artifact produced. The agent independently confirmed the staged file was still there at
full size after the call.
In both runs:
activation,agent,detection,safe-outputs-items,agent-output-fallback,usage,aic-usage-cache— and nosafe-outputs-upload-artifacts;safe_outputsjob'sDownload upload-artifact stagingstep runs and finds nothing;download-artifactforsafe-outputs-upload-artifactsfails;publish_plan,safe_outputs, and the run as a whole all report success.Expected
Either the staged file is uploaded as
safe-outputs-upload-artifacts, orupload_artifactreturnsan error the agent can act on. Returning success for an upload that did not happen means a workflow
built on this transport silently produces references to files that do not exist.
Possible cause
The agent container is given both
/tmp/gh-awand${RUNNER_TEMP}/gh-aw/safeoutputs/upload-artifactsas mounts. The tool schema served to the agentnames a staging directory under
/tmp/gh-aw, whilesafe_outputsdownloads into${RUNNER_TEMP}/gh-aw/safeoutputs/upload-artifacts/. If those are genuinely different directories,a file written to the advertised path would never be collected — which matches the observed
behaviour.
This may well be a misconfiguration on my side rather than a defect. If so, the request stands in a
smaller form: the failure should not be silent.
Note on
--helpsafeoutputs upload_artifact --helpis truncated with an ellipsis and does not show the acceptedpath formats. The full schema is only visible in
${RUNNER_TEMP}/gh-aw/mcp-cli/tools/safeoutputs.json. An agent that reads only the help text isunlikely to use the tool correctly.