Bazel "undeclared output" from an action in CI
A Bazel action must declare every file it writes. When an action writes a file the rule never declared, or fails to write a file it did declare, Bazel rejects the action and names the mismatched output.
What this error means
A genrule or custom rule fails with "declared output ... was not created by genrule" or an action reports an output file it wrote that was not declared.
ERROR: /home/runner/work/app/app/foo/BUILD.bazel:2:8: declared output
'foo/out.txt' was not created by genrule. This is probably because the genrule
actually didn't create this output, or because the output was a directory and the
genrule was run remotely.Common causes
The command did not write the declared file
The genrule cmd produced a different filename or path than the one listed in outs, so the declared output is missing.
The output is a directory or written outside the sandbox
Actions must write declared files, not directories, and only inside the action output tree; anything else is undeclared.
How to fix it
Match the command output to the declared outs
- Confirm the cmd writes to the exact path in
outsusing$@or$(location ...). - Declare a directory output with a rule that supports it if you truly emit a tree.
- Re-run so the produced file matches the declaration.
genrule(
name = "gen",
outs = ["out.txt"],
cmd = "echo hello > $@",
)Use location expansion for output paths
Reference outputs through $(location) so the command always targets the declared path Bazel expects.
cmd = "generate > $(location out.txt)"How to prevent it
- Declare exactly the files an action writes, no more and no less.
- Use
$@or$(location ...)so output paths match declarations. - Avoid writing directories or files outside the action output tree.