Skip to content

commands: Improve chtimes permission hint#14938

Open
xndvaz wants to merge 11 commits into
gohugoio:masterfrom
xndvaz:xndvaz/fix-7302
Open

commands: Improve chtimes permission hint#14938
xndvaz wants to merge 11 commits into
gohugoio:masterfrom
xndvaz:xndvaz/fix-7302

Conversation

@xndvaz

@xndvaz xndvaz commented May 25, 2026

Copy link
Copy Markdown
Contributor

Fixes #7302

Summary

  • add a targeted hint for static sync permission failures caused by chtimes
  • apply the same hint in both the build path and hugo server static sync logging
  • add focused tests for the chtimes permission case and non-matching errors

Root cause

When the publishDir is writable but not owned by the Hugo process, the OS can reject chtimes during static sync. Hugo surfaced the raw error, but did not point users to the existing --noTimes / noTimes = true workaround.

Validation

  • PATH="/Users/xndvaz/go/bin:$PATH" ./check.sh ./commands/...
  • PATH="/Users/xndvaz/go/bin:$PATH" ./check.sh

AI assistance

This PR was written with Codex assistance. I reviewed the generated changes and validation results.

@gemini-code-assist

Copy link
Copy Markdown
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize the Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counterproductive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

Comment thread commands/errors_test.go Outdated
func TestWrapStaticSyncError(t *testing.T) {
c := qt.New(t)

err := wrapStaticSyncError(&os.PathError{Op: "chtimes", Path: "public", Err: syscall.EPERM})

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In my head there are 2 types of tests:

  1. Unit tests (tests e.g. a function in isolation)
  2. Integration tests (tests more or less the entire chain with as a real a setup as practical)

This test falls between these two and I question its value. A test for a bug fix needs to 1. Demonstrate that we have fixed the bug and 2. Prevent future regressions of that same bug. The error created here is a fake one, which means that I don't know if it matches reality.

I'm assuming that testing the real scenario (e.g. with a testscript) would not be practical, so I suggest just removing the test. I have no problem seeing what the wrapper func does, and I assume it will work, and if not if will not make it worse.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed the synthetic test as suggested in 110d69d45.

I re-ran PATH="/Users/xndvaz/go/bin:$PATH" ./check.sh ./commands/... and PATH="/Users/xndvaz/go/bin:$PATH" ./check.sh locally before pushing. The PR checks are re-running now.

@bep

bep commented Jun 4, 2026

Copy link
Copy Markdown
Member

@xndvaz have you manually tested this patch and can confirm that this is works as described?

@jmooring

jmooring commented Jun 9, 2026

Copy link
Copy Markdown
Member

have you manually tested this patch and can confirm that this is works as described?

This does what it says it should do, but I don't think it improves the user experience in relation to the conditions described in #7302.

$ sudo sh -c "mkdir public && chmod a+w public"

$ hugo
Start building sites … 
hugo v0.163.0-DEV-889ce2c161636ff9e04db6f507fae5bbb273a92a+withdeploy linux/amd64 BuildDate=2026-06-01T18:48:36Z VendorInfo=jmooring

Total in 11 ms
ERROR error copying static files: chtimes /home/jmooring/code/hugo-testing/public: operation not permitted; if the publishDir is writable but not owned by the Hugo process, try --noTimes or set noTimes = true

$ hugo --noTimes  # same error when combined with --noChmod
Start building sites … 
hugo v0.163.0-DEV-889ce2c161636ff9e04db6f507fae5bbb273a92a+withdeploy linux/amd64 BuildDate=2026-06-01T18:48:36Z VendorInfo=jmooring

Total in 10 ms
ERROR error copying static files: stat /home/jmooring/code/hugo-testing/public/favicon.ico: permission denied

So you fix one error, and then encounter another. It seems to me we should just state something like "you have insufficient permissions to write files to the publishdDir".

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.

Error when building to a folder not owned by the Hugo process

3 participants