Skip to content

fix(compile): reject unknown front-matter fields with deny_unknown_fields#409

Merged
jamesadevine merged 1 commit into
mainfrom
fix/deny-unknown-front-matter-fields
May 5, 2026
Merged

fix(compile): reject unknown front-matter fields with deny_unknown_fields#409
jamesadevine merged 1 commit into
mainfrom
fix/deny-unknown-front-matter-fields

Conversation

@jamesadevine

Copy link
Copy Markdown
Collaborator

Problem

FrontMatter didn't use #[serde(deny_unknown_fields)], so serde silently ignored any YAML key that didn't match a struct field. This caused a real bug where a user wrote safeoutputs: (no hyphen) instead of safe-outputs: — the config was silently dropped, bypassing the validate_write_permissions compile-time check entirely. The result was a confusing runtime error (AZURE_DEVOPS_ORG_URL not set) instead of a clear compile-time error.

The same class of bug affected all three example files, which used top-level schedule: instead of on: schedule: — their schedules were silently ignored.

Fix

  • Add #[serde(deny_unknown_fields)] to FrontMatter so any unrecognized YAML key produces a clear compile error listing all valid fields.
  • Fix all example files and docs that used top-level schedule: (should be on: schedule:).
  • Add regression tests verifying safeoutputs: and top-level schedule: are rejected, and safe-outputs: is accepted.

Changes

File Change
src/compile/types.rs Added #[serde(deny_unknown_fields)] to FrontMatter + 3 regression tests
examples/*.md (3 files) schedule:on: schedule:
README.md Fixed full front-matter example to use on: schedule:
docs/front-matter.md Fixed reference example to use on: schedule:

Testing

  • All existing tests pass (80 integration + unit tests)
  • 3 new unit tests added
  • cargo clippy --all-targets --all-features clean

…elds

Add #[serde(deny_unknown_fields)] to FrontMatter so typos like
'safeoutputs:' (instead of 'safe-outputs:') or top-level 'schedule:'
(instead of 'on: schedule:') produce a clear compile error rather than
being silently ignored.

Previously, unknown YAML keys were silently dropped by serde, which
meant write-requiring safe-outputs could bypass the
validate_write_permissions check entirely, leading to confusing runtime
errors (e.g. 'AZURE_DEVOPS_ORG_URL not set').

Also fixes all example files and docs that incorrectly used top-level
'schedule:' instead of 'on: schedule:'.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@jamesadevine jamesadevine force-pushed the fix/deny-unknown-front-matter-fields branch from 8f5939b to 040364c Compare May 5, 2026 21:18
@jamesadevine jamesadevine merged commit 788250d into main May 5, 2026
5 checks passed
@jamesadevine jamesadevine deleted the fix/deny-unknown-front-matter-fields branch May 5, 2026 21:19
@github-actions

github-actions Bot commented May 5, 2026

Copy link
Copy Markdown
Contributor

🔍 Rust PR Review

Summary: Solid fix for a real silent-failure bug. One minor documentation typo was introduced alongside the fix.

Findings

🐛 Bugs / Logic Issues

  • docs/front-matter.md:26 — The refactor accidentally dropped the space before # on the workspace line:
    workspace: repo# Optional: "root", "repo" ...
    In YAML, # only starts a comment when preceded by whitespace. Without the space, the full string repo# Optional: "root", "repo" ... would be the parsed value rather than repo with a comment. Any user who copy-pastes this example verbatim will get an invalid workspace value. Easy fix: restore the space → workspace: repo # Optional: ...

✅ What Looks Good

  • #[serde(deny_unknown_fields)] is exactly the right tool here. It surfaces misconfigured keys as compile-time errors rather than silently dropping them, which is a meaningful security/correctness improvement for a compiler that processes untrusted input.
  • The three regression tests are well-chosen: they cover the motivating bug (safeoutputs without hyphen), the example-file bug (top-level schedule), and a positive case confirming the correct spelling still works.
  • All example files and the README were consistently updated — no stragglers.
  • Error message assertions (err.contains("unknown field \safeoutputs`")`) are appropriately specific without over-constraining serde's internals.

Generated by Rust PR Reviewer for issue #409 · ● 183.3K ·

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.

1 participant