Summary
safe-outputs.create-issue.deduplicate-by-title passes schema validation and is documented, but the compiler never serializes it into the generated .lock.yml safe-outputs config. The runtime handler (issue_title_dedup.cjs) reads config.deduplicate_by_title, which is therefore always undefined — so configuring the field has no effect. No error, no warning; it silently does nothing.
Repro
wf.md:
---
on: workflow_dispatch
engine: copilot
strict: false
safe-outputs:
create-issue:
deduplicate-by-title: 1
max: 3
---
# t
body
$ gh aw compile wf.md --validate --approve
✓ Compiled 1 workflow(s): 0 error(s), 0 warning(s)
$ grep -oE '"create_issue":\{[^}]*\}' wf.lock.yml
"create_issue":{"max":3} # <- no deduplicate_by_title
$ grep -ci deduplicate wf.lock.yml
0
Expected
The emitted create_issue safe-outputs config contains deduplicate_by_title (e.g. "deduplicate_by_title":1) so the runtime parseDeduplicateByTitle(config.deduplicate_by_title) path is active.
Actual
deduplicate-by-title is parsed-and-dropped; absent from the lock entirely. Title-based dedup never runs.
Root cause
The compiler config struct in pkg/workflow/create_issue.go has no field for it. The struct binds the sibling options but not this one:
TitlePrefix string `yaml:"title-prefix,omitempty"`
Labels []string `yaml:"labels,omitempty"`
CloseOlderIssues *string `yaml:"close-older-issues,omitempty"`
CloseOlderKey string `yaml:"close-older-key,omitempty"`
GroupByDay *string `yaml:"group-by-day,omitempty"`
Expires int `yaml:"expires,omitempty"`
Group *string `yaml:"group,omitempty"`
// (no `yaml:"deduplicate-by-title"` binding)
Meanwhile the runtime expects it — actions/setup/js/issue_title_dedup.cjs exports parseDeduplicateByTitle(), and create_issue.cjs calls parseDeduplicateByTitle(config.deduplicate_by_title). The frontmatter→config wiring is the missing link.
Versions affected
Validates-but-drops on v0.75.4, v0.76.1, v0.77.5, v0.77.6 (the struct lacks the field in all). v0.74.3 rejects it outright (Unknown property: deduplicate-by-title), so the field appears to have been added to the schema/docs/runtime around v0.75 without the compiler binding.
Impact
Workflows relying on deduplicate-by-title for per-finding issue dedup get duplicate issues with no indication the setting is inert.
Summary
safe-outputs.create-issue.deduplicate-by-titlepasses schema validation and is documented, but the compiler never serializes it into the generated.lock.ymlsafe-outputs config. The runtime handler (issue_title_dedup.cjs) readsconfig.deduplicate_by_title, which is therefore always undefined — so configuring the field has no effect. No error, no warning; it silently does nothing.Repro
wf.md:Expected
The emitted
create_issuesafe-outputs config containsdeduplicate_by_title(e.g."deduplicate_by_title":1) so the runtimeparseDeduplicateByTitle(config.deduplicate_by_title)path is active.Actual
deduplicate-by-titleis parsed-and-dropped; absent from the lock entirely. Title-based dedup never runs.Root cause
The compiler config struct in
pkg/workflow/create_issue.gohas no field for it. The struct binds the sibling options but not this one:Meanwhile the runtime expects it —
actions/setup/js/issue_title_dedup.cjsexportsparseDeduplicateByTitle(), andcreate_issue.cjscallsparseDeduplicateByTitle(config.deduplicate_by_title). The frontmatter→config wiring is the missing link.Versions affected
Validates-but-drops on v0.75.4, v0.76.1, v0.77.5, v0.77.6 (the struct lacks the field in all). v0.74.3 rejects it outright (
Unknown property: deduplicate-by-title), so the field appears to have been added to the schema/docs/runtime around v0.75 without the compiler binding.Impact
Workflows relying on
deduplicate-by-titlefor per-finding issue dedup get duplicate issues with no indication the setting is inert.