Skip to content

Document GitHub Contents API create_or_update_file base64 footgun in a runbook/CONTRIBUTING note #342

Description

@nsheaps

Context

During PR #340, plugins/claude-code/review-utils/actions/run-agent/action.yaml was corrupted twice by passing pre-base64-encoded content into mcp__github__create_or_update_file's content parameter. That tool (like the underlying GitHub Contents API) base64-encodes its input internally — passing already-encoded content produces base64(YAML) on disk instead of plain YAML. A subsequent mise run format auto-fix-and-commit re-wrapped the already-corrupted content a second time, producing base64(base64(YAML)).

The recovery approach that worked (used in commit 0533a23):

git show origin/main:<path> > <path>
# ...apply the intended edit locally with a normal text editor/Edit tool...
head -1 <path>                                    # sanity-check first line
wc -c <path>                                       # compare size to a known-good ref
python3 -c 'import yaml; d = yaml.safe_load(open("<path>")); assert isinstance(d, dict)'  # mapping-shape check, not just "parses"

Proposal

Add a short runbook note (CONTRIBUTING.md or a docs/ page, wherever similar operational gotchas are documented) covering:

  1. create_or_update_file's content parameter expects raw plain text, never pre-encoded — the tool/API encodes it internally.
  2. When fixing a file suspected of encoding corruption, prefer local git (git show <ref>:<path> > <path>, edit, commit, push) over the Contents-API write tool, since it sidesteps this class of bug entirely.
  3. yaml.safe_load() succeeding is not sufficient verification for "is this valid YAML" when the file's expected shape is a mapping (e.g., a composite action) — also assert the parsed type/shape, not just that parsing didn't raise.

References

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions