diff --git a/docs/src/github-action.md b/docs/src/github-action.md
index fa7cc3d..adfd089 100644
--- a/docs/src/github-action.md
+++ b/docs/src/github-action.md
@@ -459,6 +459,7 @@ land on the recipe.
| `Could not find SBOM at services/api` after a green earlier run | Default branch protection bumped the merge-base; `before-ref` now points at a commit that predates the `services/api` directory | Either move the `path:` value to match the new layout, or pin `before-ref` explicitly to a known-good commit (`before-ref: main`). |
| `cosign: signature verification failed` after a release-archive rotation | Cached release archive in the runner's tool cache is stale and predates a rotation | Bump to the latest patch tag (e.g. `Metbcy/bomdrift@v1` re-resolves to the floating tag), or set `verify-signatures: false` on a self-hosted runner you've pinned manually. |
| `path: services/api` warning + empty SBOM | The path doesn't exist post-checkout — typo, or the directory was renamed in `before-ref` only | bomdrift v0.7+ surfaces an actionable error pointing at this exact case. See the [monorepo section](#monorepo-setup) for the matrix recipe; double-check `${{ matrix.service }}` substitution. |
+| `scan path not found:
` with directory listing | The `path:` input resolves to a directory that does not exist in this checkout. The error prints what was actually present at the checkout root, plus an event-specific hint (PR vs push/workflow_dispatch) | Fix the `path:` input typo, OR if the directory only exists on one side of the diff, pin `before-ref` explicitly (e.g. `before-ref: main`) or supply `before-sbom`. On non-PR events the default `before-ref` is the parent commit, which often predates a newly-added monorepo subdirectory — see the [monorepo section](#monorepo-setup). bomdrift does NOT silently fall back to the repo root, because that would produce a misleading diff. |
| "Comment exceeds 65,536 characters" 422 from GitHub | A massive diff blew past the size cap; the v0.3 fallback to `--summary-only` was disabled (`comment-size-limit: 0`) | Re-enable the fallback (drop `comment-size-limit` to use the default, or set it to `60000`). The full body is preserved in the workflow step summary. |
| Action runs, no PR comment appears, exit 0 | Workflow event isn't `pull_request` (the comment path is gated on PR events), or `comment-on-pr: false` was set explicitly | For `push`/`schedule` events, the comment path is intentionally skipped — use the step summary or upload the markdown as an artifact. |
diff --git a/entrypoint.sh b/entrypoint.sh
index 67eeff4..2f3e6aa 100755
--- a/entrypoint.sh
+++ b/entrypoint.sh
@@ -220,6 +220,25 @@ generate_sbom() {
if [ -z "$actual" ]; then
actual=" (checkout root is empty)"
fi
+ # Event-specific hint: on non-pull_request events (push, workflow_dispatch,
+ # schedule) the merge-base isn't auto-resolved, so 'before-ref' often points
+ # at a commit that predates the directory you're scanning. Surface that
+ # explicitly rather than making the user infer it from "before-ref".
+ local event_hint=""
+ case "${GITHUB_EVENT_NAME:-}" in
+ pull_request|pull_request_target) ;;
+ "")
+ event_hint="
+ - running outside GitHub Actions: ensure the working tree at '${checkout_dir}'
+ actually contains '${clean}' (this is usually a local-test misconfiguration)"
+ ;;
+ *)
+ event_hint="
+ - non-PR event (${GITHUB_EVENT_NAME}): 'before-ref' defaults to the parent
+ commit, which may predate '${clean}'. Pin 'before-ref' to a known-good
+ commit (e.g. 'before-ref: main') or supply 'before-sbom' directly"
+ ;;
+ esac
fail "scan path not found: ${source_dir}
Resolved from input path='${subpath}' against checkout '${checkout_dir}'.
The checkout root contains:
@@ -228,9 +247,23 @@ ${actual}
Common causes:
- typo in the 'path:' input (case-sensitive; 'Services/api' != 'services/api')
- the directory exists in after-ref but not before-ref (or vice versa)
- - a monorepo split renamed the directory in the default branch since the PR was opened
- See https://metbcy.github.io/bomdrift/github-action.html#monorepo-setup
- for the matrix-per-service recipe."
+ - a monorepo split renamed the directory in the default branch since the PR was opened${event_hint}
+
+ For monorepos, use a matrix per service so each leg has its own 'path:':
+
+ strategy:
+ matrix:
+ service: [api, web, worker]
+ steps:
+ - uses: metbcy/bomdrift@v1
+ with:
+ path: services/\${{ matrix.service }}
+
+ Full recipe: https://metbcy.github.io/bomdrift/github-action.html#monorepo-setup
+
+ This failure is intentional: bomdrift does NOT silently fall back to the
+ repository root because that would scan unrelated code and produce a
+ misleading diff. Fix the 'path:' input or the ref pinning above."
fi
if ! command -v syft >/dev/null 2>&1; then