Skip to content

defect: YAML indentation bug in compiler causes job permissions block to be mis-indented #23643

@grahame-white

Description

@grahame-white

Root Cause Analysis: Workflow YAML Indentation Issue

Defect:
The compiled workflow YAML for workflows using gh-aw/github/gh-aw sometimes produces mis-indented blocks for job-level keys such as permissions:, leading to syntactically invalid or semantically incorrect YAML structures. The example below is based on a real scenario reported downstream (discussion link):

  detection:
    needs: agent
    if: >
      always() && needs.agent.result != 'skipped' && (needs.agent.outputs.output_types != '' || needs.agent.outputs.has_patch == 'true')
    runs-on: ubuntu-latest
    permissions:
          copilot-requests: write

Here, copilot-requests: write is incorrectly indented by two levels instead of one (should be under permissions: by a single level, matching GitHub Actions' YAML spec).


Root Cause (Hypothesized)

  • Source of Generation: Workflows are written in markdown then compiled to YAML via the gh-aw compiler. The compiler translates high-level constructs or embedded markdown/code snippets into YAML, applying default or templated indentation logic.
  • Indentation Handling: There is likely an off-by-one bug in the indentation engine/routines within the gh-aw compiler:
    • When processing nested keys (like permissions sub-blocks), the compiler may incorrectly count the indentation for child keys, especially when inserting or transforming lines based on special-cased jobs/blocks.
    • It may treat some values as collections/lists, causing additional indentation to be applied mistakenly.
  • Regression Trigger:
    • Changes to the compiler logic or embedded defaults for block emission.
    • Introduction of new job structures or custom logic (e.g., for permissions, environment, or conditional blocks) without updating the YAML emission routines.
    • Markdown-to-YAML transformation routines failing to align with GitHub Actions' expectations for block/mapping indentation.
  • Downstream Impact:
    • YAML parser errors, or silent misconfiguration due to keys being ignored/misread.
    • Security/permission bugs if permissions are not what was intended.

How to Reproduce

  1. Write a workflow in markdown with a job containing a permissions: block (especially with only one entry).
  2. Compile with gh-aw compile (with the current/affected version).
  3. Inspect the output YAML: if the sub-keys under permissions: are indented by more than one level, this defect occurs.
  4. Compare the indentation of permissions: in different jobs (e.g., compare detection and agent jobs if available).

Recommendation

  • Ensure that the YAML emitter/renderer in gh-aw tracks the correct indentation depth for nested keys.
  • Add targeted tests that compare output YAML structure/indentation for job-level keys (including permissions) to known-good workflows (such as those generated by the GitHub Actions editor UI or manually written YAML).
  • Audit/workflow for any other block-level fields prone to indentation issues.

Reference

See downstream integration failure and the discussion.


Checklist

  • Downstream usage affected (see linked PR/discussion)
  • Indentation bug is visible in generated YAML
  • Appears to be a compiler/codegen issue (not user YAML error)

Impact

This can break workflow execution, block CI, and lead to security errors if permission blocks are not applied as intended.

Metadata

Metadata

Labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions