Skip to content

Surface run:command stderr and fail fast on command errors#286

Merged
kategengler merged 3 commits into
mainfrom
copilot/copilotfix-run-command-error-reporting
Jun 3, 2026
Merged

Surface run:command stderr and fail fast on command errors#286
kategengler merged 3 commits into
mainfrom
copilot/copilotfix-run-command-error-reporting

Conversation

Copilot AI commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

run:command made command failures hard to diagnose because only stdout was surfaced; stderr was effectively lost in rendered output. This change ensures command errors are visible and immediately halt tutorial execution.

  • Error visibility

    • Capture stderr alongside stdout on successful command execution.
    • Include both streams in captured output when captureOutput is enabled.
  • Fail-fast behavior

    • On exec failure, emit any available error.stdout / error.stderr.
    • Rethrow the original error so directive execution stops at the failing command.
  • Operational impact

    • Failures like tutorial setup command/patch mismatches now expose actionable diagnostics directly at the failing step instead of appearing opaque.
try {
  let { stdout, stderr } = await exec(cmd, { cwd });

  if (args.captureOutput) {
    if (stdout) output.push(stdout);
    if (stderr) output.push(stderr);
  }
} catch (error: any) {
  if (args.captureOutput) {
    if (error.stdout) output.push(error.stdout);
    if (error.stderr) output.push(error.stderr);
  }

  throw error;
}
Original prompt

Create a pull request in ember-learn/super-rentals-tutorial for the already-implemented branch copilot/fix-run-command-error-reporting.

Context:

  • A workflow job failed because command errors from the tutorial runner were not being surfaced clearly.
  • The requested fix was to improve error reporting from run:command and ensure the tutorial stops immediately if a command errors.
  • The change has already been committed on branch copilot/fix-run-command-error-reporting.

Implemented change:

  • Updated src/lib/plugins/run-code-blocks/directives/command.ts
  • run:command now captures and emits stderr in addition to stdout
  • On command failure, it logs available stdout/stderr and rethrows the error so execution halts immediately

Commit to include:

  • 8eb214042ffb21f62f26b27016be1b90a95b7ecd

Please open a PR from copilot/fix-run-command-error-reporting into main with a concise title and description summarizing:

  • the previous behavior (stderr was effectively hidden and failures were less diagnosable)
  • the new behavior (stderr is surfaced and failures stop execution immediately)
  • why this helps diagnose failures like the tutorial ember new setup problem

The following is the prior conversation context from the user's chat exploration (may be truncated):

User: This job failed because ember new super-rentals --lang en --strict --pnpm did not succeed. But there is no error output and the tutorial continues. What is swallowing the error and how can we fix it?

Assistant: The error is not being swallowed by ember new. It’s being hidden by the tutorial runner’s run:command directive, which only captures stdout and drops stderr. The actual failure happens later, when a patch step assumes super-rentals/index.html exists, but the generated app no longer has that file. So the job appears to “continue” past ember new, then fails on git apply.

Two fixes are needed:

  1. Surface command failures properly in run:command by capturing and printing stderr from failed commands.
  2. Update the tutorial step that patches index.html, because the app now appears to use dist/code/super-rentals/index.html no longer exists at that location after ember new --strict --pnpm. The failing patch is targeting super-rentals/index.html, which does not exist in the generated app.

Here’s the evidence:

  • The job log’s real error is:
    • Error: Command failed: git apply
    • error: dist/code/super-rentals/index.html: No such file or directory
  • That means ember new completed far enough for the tutorial to move on, but the next run:file:patch step failed. The failing workflow job is from .github/workflows/build.yml, run 26864808120, job 79327181365.
  • In the tutorial markdown, right after the ember new super-rentals --lang en --strict --pnpm block, there is a hidden patch step against cwd=super-rentals filename=index.html, so the runner tries to apply a patch to dist/code/super-rentals/index.html. That file path is now wrong.
  • The patch directive directly shells out to git apply, and if the file is missing it throws immediately.
  • The command directive uses await exec(cmd, { cwd }) and destructures only { stdout }, so on failure it does not append stderr into the rendered tutorial output; it just throws. That is why users don’t see the actual command error in the tutorial output.

Relevant code:

let output: string[] = [];

for (let { command: cmd, display } of parseCommands(node.value, options.cfg, node)) {
  console.log(`$ ${cmd}`);

  if (args.captureCommand) {
    output.push(`$ ${display}`);
  }

  let { stdout } = await exec(cmd, { cwd });

  if (args.captureOutput) {
    output.push(stdout);
  }

  console.log(stdout)
}
async function applyPatch(patch: string, cwd: string): Promise<void> {
  let promise = exec('git apply', { cwd });
  promise.child.stdin!.end(patch, 'utf-8');
  await promise;
}
```run:command
# We are supposed to (?) use NPM for the guides, but pnpm works better
# for our setup, so we pass the `--pnpm` flag but change the output to
# pretend we are running NPM.

#[cfg(all(ci, unix))]
#[display(ember new super-rentals --lang en --strict)]
ember new super-rentals --lang en --strict --pnpm \
  | awk '{ gsub("Pnpm",...

</details>



<!-- START COPILOT CODING AGENT SUFFIX -->

*This pull request was created from Copilot chat.*
>

Copilot AI changed the title [WIP] Fix command error reporting in tutorial runner Surface run:command stderr and fail fast on command errors Jun 3, 2026
Copilot AI requested a review from kategengler June 3, 2026 19:10
@kategengler

Copy link
Copy Markdown
Contributor

@copilot No files have been changed

Copilot AI commented Jun 3, 2026

Copy link
Copy Markdown
Contributor Author

@copilot No files have been changed

Addressed in commit 67825e7. The run:command directive now captures stderr (and stdout) on success and on command failure before rethrowing, so failures surface actionable diagnostics and stop execution immediately.

@kategengler kategengler marked this pull request as ready for review June 3, 2026 19:44
@kategengler kategengler merged commit 1e64dc7 into main Jun 3, 2026
3 of 6 checks passed
@kategengler kategengler deleted the copilot/copilotfix-run-command-error-reporting branch June 3, 2026 19:44
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