GitHub Actions working-directory Error Explained

Summary

Pixel’s announcement explains why GitHub Actions rejects working-directory on a uses step instead of silently ignoring it. It shows how the Invalid workflow file message appears before any job runs, identifies common causes, and clarifies the difference between action steps and run steps.

DEV Community

GitHub Actions working-directory on a uses step is rejected, not ignored

GitHub Actions working-directory on a uses step is refused by the workflow schema before anything runs, so the belief that the key is accepted and quietly ignored is backwards. There is no wrong directory to debug, because the file never compiled and no job was ever created. A step is one of two shapes. Reading uses narrows the reader to the shape that has no working-directory property, and the next key has nowhere to go. What this error means You added a directory to a step that calls an action, pushed, and the workflow did not run. In the Actions tab the file is flagged rather than the job, and the annotation names a line and a column and quotes the key you added. If you are reading a stale answer that says the key is silently ignored, the thing to check is whether your run exists at all: an ignored key produces a green run that did the wrong work, and a rejected key produces no run. ```Message text from TemplateStrings.UnexpectedValue in actions/runner Invalid workflow file: .github/workflows/ci.yml#L12 (Line: 12, Col: 9): Unexpected value 'working-directory'

Common causes

The key was copied from a run step onto a uses step

Overwhelmingly the commonest origin. Somebody had a working run step with a directory on it, replaced the command with an action, and kept the surrounding keys. The diff looks harmless because only the middle line changed.

An answer elsewhere said the key is ignored rather than refused

The claim that a uses step accepts working-directory and quietly does nothing with it is widespread and wrong. It matters because the two behaviors need opposite responses: an ignored key means hunting for why the action used the wrong path, and a refused key means the run you are looking for does not exist.

The action really has no way to take a path

Some actions assume the repository root and offer no input for anything else. Reaching for working-directory is the natural next move, and the schema refuses it, which leaves the reader convinced the key is broken rather than absent.

The directory belonged on the job, not the step

When every step in a job works in the same subdirectory, per-step keys accumulate until one of them lands on an action. In our experience this is the version that survives review, because each individual line looks like the line above it.

How to fix it

Pass the path as an input the action declares

Open the action's action.yml and read the inputs block. Most actions that touch the filesystem expose a path, a working-directory or a source input. Passing it under with is the only mechanism the step shape offers, and it is the one the action author tested.

.github/workflows/ci.yml (illustrative) - uses: some-org/build-action@v1 with: path: packages/app Set the directory once for the job, for run steps Move the directory to defaults.run.working-directory on the job. It applies to every run step in the job and to none of the actions, which is exactly the boundary the schema draws, so nothing is left ambiguous for the next reader..github/workflows/ci.yml (illustrative) jobs: build: defaults: run: working-directory: packages/app

Wrap the action in a run step when it takes no path

  1. Check the action's action.yml once more for any input that accepts a path.
  2. If there is none, replace the action with the command it wraps, in a run step that carries the directory.
  3. If the action does real work you do not want to reimplement, prepare the directory in a run step before it, so the action still sees the layout it expects at the repository root.

Split the job when two directories are genuinely involved

A job whose steps work in two places is asking one defaults block to be two values. Two jobs, each with its own default, expand into a clearer run page and let you give them different conditions later. The cost is one extra checkout, which a cache usually absorbs.

How to prevent it

  • Validate workflow files in the editor, wh...
    GitHub Actions working-directory Error Explained
    Powered by Readybot.io

The latest from Pixel

Fix GitHub Pages: Missing Artifact Error

Pixel's announcement explains why the GitHub Pages deploy action reports that no github-pages artifact was found. It covers skipped or failed build jobs, missing uploads, …

Rotate DB and Redis Passwords Without Downtime

Pixel shares a practical guide to rotating exposed database and Redis passwords without interrupting application connections. The approach updates Secrets, changes service credentials, and gradually …

AI Agent Receipts Prove What Actually Executed

Pixel’s announcement examines how public Zambo receipts verify what an AI agent actually did. A BTC price fetch succeeded with a recomputable output hash, while …