Skip to content

feature-ideation: discussion-triggered run fails at workflow setup (zero jobs) — discussion→dispatch bridge #571

Closed

Description

@don-petry

Summary

A feature-ideation run triggered by a new Ideas Discussion fails immediately at workflow setup — zero jobs are created (GitHub: "This run likely failed because of a workflow file issue", conclusion=failure, total_jobs=0). The discussion → workflow_dispatch redispatch bridge (added in #550, building on #457/#448) appears to be broken on the discussion event path, and this looks like its first real-world exercise.

Evidence

  • Failing run: https://github.com/petry-projects/bmad-bgreat-suite/actions/runs/28534194854 (event=discussion, conclusion=failure, 0 jobs).
  • Trigger: petry-projects/bmad-bgreat-suite Discussion Org Status — 2026-05-22 #344 "enhanced devops agent persona", category ideas, author don-petry (OWNER, not a bot) → the redispatch job's if: (ideas category + OWNER/MEMBER/COLLABORATOR + non-bot) would have matched. Since no jobs were created at all (not "skipped"), the failure is a workflow-file/validation error at setup, before any job if: is evaluated.
  • Not a bad copy: bmad's .github/workflows/feature-ideation.yml is byte-identical to the current standards/workflows/feature-ideation.yml template (verbatim enrollment, reusable pinned @e20a8fac # v1).
  • Never succeeded via discussion: no discussion-triggered feature-ideation run has succeeded anywhere in the org (this path was only recently deployed).

Likely root cause (hypothesis — exact "Invalid workflow file" text not retrievable via API for startup failures)

The caller defines the redispatch inline (redispatch job on discussion, plus an ideate job if: github.event_name != 'discussion' that calls the reusable with a with: block full of ${{ inputs.* }} references). On a discussion event there is no inputs context, and GitHub validates the reusable-call graph (including the ideate job's with:) at setup time regardless of its if: — a plausible trigger for the zero-job compile failure.

Contrast: initiative-planner.yml is a thin caller (uses: + secrets: inherit, no inline redispatch, no with: inputs.*) whose reusable performs the redispatch internally — and it works correctly on discussion events (validated same day: TalkTerm idea:approved → inert epic #333 + DAG).

Impact

Suggested fix directions

  1. Mirror initiative-planner.yml's architecture — make the caller a thin stub and move the discussion→dispatch redispatch into the reusable (which runs under a context where the reusable-call graph validates cleanly), or
  2. Keep the inline bridge but ensure the ideate reusable job's with: does not force ${{ inputs.* }} evaluation on discussion events (e.g. gate via a computed job output / avoid referencing inputs where it's absent).

Please confirm the exact setup error from the run's UI ("Invalid workflow file …") when triaging.

Repro

  1. In a repo with feature-ideation.yml (@e20a8fac), open a Discussion in the Ideas category as an OWNER/MEMBER.
  2. Observe the feature-ideation run fail at setup with 0 jobs.

Refs: #550, #457, #448 · rollout context combsmith/.github-private#978, #515.

Activity

  1. added
    bugBug reports
    ciCI/CD pipeline issues
    dev-leadFor dev-lead agent pickup
    on Jul 1, 2026
  2. don-petry commented on Jul 2, 2026

    @don-petry
    ContributorAuthor

    Dev-Lead Implementation Plan

    Issue: #571 — feature-ideation: discussion-triggered run fails at workflow setup (zero jobs) — discussion→dispatch bridge

    Root cause

    The feature-ideation.yml caller defines the reusable call (ideate job) with a with: block that references ${{ inputs.* }}. GitHub validates the reusable-call graph (including with:) at setup time regardless of the job if:. On a discussion event there is no inputs context, which trips the zero-job "Invalid workflow file" compile failure — so redispatch never even gets a chance to run.

    Scope

    Adopt suggested fix direction #2: keep the inline discussion→dispatch bridge, but make the reusable-call with: block never reference ${{ inputs.* }}. Dispatch inputs are computed in a gated prep job and forwarded via needs.prep.outputs.* (an always-valid context). Add a regression lint + test so the anti-pattern can't come back.

    Implementation Checklist

    • standards/workflows/feature-ideation.yml — add a gated prep job that echoes inputs.* to job outputs; change ideate to needs: [prep] and source its with: from needs.prep.outputs.*; keep redispatch bridge
    • .github/workflows/feature-ideation.yml — apply the same structure to this repo's own caller (dogfood; it carries the same latent bug)
    • .github/scripts/feature-ideation/lint-caller.sh — fail when a job-level reusable uses: has a with: value referencing ${{ inputs.* }}
    • .github/workflows/feature-ideation-tests.yml — install pyyaml, add script to shellcheck list, add a "lint caller" gate step
    • standards/ci-standards.md §9 — document the redispatch-bridge + prep-outputs architecture (currently documents the superseded direct target_discussion pass)

    Tests to Write

    • test/workflows/feature-ideation/lint-caller.bats — clean fixture passes; inputs.*-in-reusable-with: fixture fails with the offending key; step-level action uses: produces no false positive; the real template and real repo caller both pass (regression guards — red before the fix)
    • fixtures under test/workflows/feature-ideation/fixtures/callers/

    Test Command

    bats test/workflows/feature-ideation/ (plus bash .github/scripts/feature-ideation/lint-caller.sh <files> and bash .dev-lead/scripts/dev-lead-lint.sh)

  3. don-petry commented on Jul 2, 2026

    @don-petry
    ContributorAuthor

    Dev-Lead: issue #571 implementation failed — will retry

    The engine failed (engine-error — e.g. a timeout or transient engine error). This was attempt 1 of 3; dev-lead will retry automatically. You can also re-apply the dev-lead label to retry now.

  4. don-petry commented on Jul 2, 2026

    @don-petry
    ContributorAuthor

    Dev-Lead: issue #571 implementation failed — will retry

    The engine failed (engine-error — e.g. a timeout or transient engine error). This was attempt 2 of 3; dev-lead will retry automatically. You can also re-apply the dev-lead label to retry now.

  5. don-petry commented on Jul 2, 2026

    @don-petry
    ContributorAuthor

    Dev-Lead: cannot implement issue #571 — needs human attention

    Automatic retries are exhausted (attempt 3 of 3). The most recent failure was engine-error.

    Last 40 lines of engine output (redacted)
        [copilot] calling gh copilot (model=openai/o4-mini, timeout=600s, flags=--yolo)
    Error: Classic Personal Access Tokens (ghp_) are not supported by Copilot.
    
    The GH_TOKEN environment variable contains a classic PAT.
    Please use a Fine-Grained Personal Access Token or another authentication method.
    
    To fix this, you can:
      • Replace the token in GH_TOKEN with a fine-grained PAT
      • Unset GH_TOKEN and run 'gh auth login' to authenticate
      • Unset GH_TOKEN and start 'copilot', then use the '/login' command
    
    

    Please review the failures above. To retry anyway, remove the dev-lead:needs-human label and re-apply the dev-lead label.

  6. added
    dev-leadFor dev-lead agent pickup
    dev-lead:needs-humandev-lead could not complete this issue; needs human attention
    and removed
    dev-leadFor dev-lead agent pickup
    dev-lead:needs-humandev-lead could not complete this issue; needs human attention
    on Jul 4, 2026
  7. don-petry commented on Jul 4, 2026

    @don-petry
    ContributorAuthor

    Dev-Lead: cannot implement issue #571 — needs human attention

    Automatic retries are exhausted (attempt 4 of 3). The most recent failure was engine-error.

    Please review the failures above. To retry anyway, remove the dev-lead:needs-human label and re-apply the dev-lead label.

  8. 1 remaining item

  9. don-petry commented on Jul 4, 2026

    @don-petry
    ContributorAuthor

    Fixed and validated end-to-end ✅

    Root cause confirmed. A reusable-workflow call graph (uses: + with:) is evaluated at workflow setup, before and regardless of the calling job's if:. The ideate job's with: referenced ${{ inputs.* }}, and the inputs context isn't populated on the discussion event → the whole run failed at setup with zero jobs, even though ideate was gated if: github.event_name != 'discussion'. (Note: this is a runtime setup failure, not static-lintable — actionlint passes the broken file.)

    Fix. Resolve dispatch inputs in a gated prep job and pass them to ideate via needs.prep.outputs.* — an always-valid context that defers the with: evaluation to run time (skipped on discussion). Mirrors the working initiative-planner.yml bridge.

    Live validation (petry-projects/.github-private, next ring): opened a real Ideas Discussion and observed the discussion-triggered run:

    • discussion run → 3 jobs, redispatch: success, prep/ideate correctly skipped — no zero-job startup failure.
    • redispatch bridged to workflow_dispatch → 4 jobs, prep: success, ideate ran with target_discussion forwarded through needs.prep.outputs.*.

    Contrast: the pre-fix discussion runs failed at setup. The bridge now works.

    Fleet rollout. The other repos' callers still carry the same latent inputs.* pattern until re-synced to the fixed template — tracked in #614 (each repin/onboard now picks up the fix, and the new lint-caller.sh prevents regressions).

    Closing as fixed.

  10. removed
    dev-leadFor dev-lead agent pickup
    dev-lead:needs-humandev-lead could not complete this issue; needs human attention
    on Jul 4, 2026
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

    bugBug reportsciCI/CD pipeline issues

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions