Skip to content

fix: truncate long lines before tfmask to prevent bufio.Scanner crash on apply#426

Open
bennymagid wants to merge 5 commits intodflook:mainfrom
doppelxyz:fix/tfmask-long-line-bufio-scanner
Open

fix: truncate long lines before tfmask to prevent bufio.Scanner crash on apply#426
bennymagid wants to merge 5 commits intodflook:mainfrom
doppelxyz:fix/tfmask-long-line-bufio-scanner

Conversation

@bennymagid
Copy link
Copy Markdown

Describe your changes

  • Add a Python line-length guard before $TFMASK in the plan pipeline
  • Lines exceeding 65000 chars are truncated with a [line truncated for display] suffix before reaching tfmask

Why

tfmask uses Go's bufio.Scanner which has a 64KB per-line limit. Terraform resources that embed large base64 blobs in plan output (e.g. google_api_gateway_api_config with openapi_documents) produce single lines exceeding this limit.

When tfmask crashes mid-pipe, terraform receives SIGPIPE and exits with a non-standard code. PIPESTATUS[0] captures that bad code, neither PLAN_EXIT -eq 0 nor PLAN_EXIT -eq 2 matches, set_output changes is never called, and the apply step is silently skipped with "No plan changes detected" — even when there are real changes to apply.

Test Plan

  • Verified root cause by tracing bufio.Scanner: token too long error in CI logs through the pipeline exit code flow to the skipped apply
  • The fix prevents tfmask from ever seeing oversized lines; normal lines are unaffected and still masked

GCP Changes

None

naveenOnarayanan and others added 5 commits December 14, 2025 20:01
tfmask is a Go binary that reads plan output line-by-line using
bufio.Scanner, which has a default 64KB buffer limit. Terraform resources
that embed large base64 blobs in their plan output (e.g.
google_api_gateway_api_config with openapi_documents) produce single lines
that exceed this limit.

When tfmask crashes mid-pipe, terraform receives SIGPIPE and exits with a
non-standard code (not 0 or 2). PIPESTATUS[0] then captures that bad code,
neither branch of the PLAN_EXIT check matches, set_output changes is never
called, and the apply step is skipped with "No plan changes detected".

Fix: add a Python pre-processor before tfmask that truncates any line
exceeding 65000 chars. This preserves tfmask's secret-masking for all
normal lines while preventing it from crashing on oversized blob lines.
The truncated content only affects the human-readable plan display in
plan.txt — it has no effect on whether changes are detected or applied.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…content

Instead of truncating lines that exceed bufio.Scanner's 64KB limit, split
them into 60KB chunks with a sentinel prefix (##TF_CHUNK:i/total/content)
before tfmask, then reassemble after. This prevents the tfmask crash while
keeping the complete plan output intact for downstream consumers.
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.

2 participants