golang/go · error

%s exists but is writable

Error message

%s exists but is writable

What it means

Thrown by the exists command (with -readonly flag) in the Go test script framework when a file exists but has any write permission bit set (mode & 0o222 != 0). The command asserts that files should be read-only; if any of owner/group/other write bits are set, it fails.

Source

Thrown at src/cmd/internal/script/cmds.go:614

				case "-exec":
					exec = true
					args = args[1:]
				default:
					break loop
				}
			}
			if len(args) == 0 {
				return nil, ErrUsage
			}

			for _, file := range args {
				file = s.Path(file)
				info, err := os.Stat(file)
				if err != nil {
					return nil, err
				}
				if readonly && info.Mode()&0222 != 0 {
					return nil, fmt.Errorf("%s exists but is writable", file)
				}
				if exec && runtime.GOOS != "windows" && info.Mode()&0111 == 0 {
					return nil, fmt.Errorf("%s exists but is not executable", file)
				}
			}

			return nil, nil
		})
}

// Grep checks that file content matches a regexp.
// Like stdout/stderr and unlike Unix grep, it accepts Go regexp syntax.
//
// Grep does not modify the State's stdout or stderr buffers.
// (Its output goes to the script log, not stdout.)
func Grep() Cmd {
	return Command(
		CmdUsage{

View on GitHub (pinned to b6b368adc5)

Solutions

  1. Run `chmod 0444 file` or `chmod 0555 file` in the script before the exists -readonly check.
  2. Verify that the file creation step is followed by an explicit chmod to remove write bits.
  3. Check that no prior step re-adds write permissions after the chmod.

Example fix

// Before:
// exists -readonly file.txt
//
// After (add chmod first):
// chmod 0444 file.txt
// exists -readonly file.txt
Defensive patterns

Strategy: validation

Validate before calling

// Ensure file is read-only before asserting exists -readonly:
// In the test script:
// chmod 0444 file.txt
// exists -readonly file.txt

// Programmatic check:
func ensureReadOnly(path string) error {
    info, err := os.Stat(path)
    if err != nil { return err }
    if info.Mode() & 0222 != 0 {
        return os.Chmod(path, info.Mode() & ^fs.FileMode(0222))
    }
    return nil
}

Prevention

When it happens

Trigger: exists -readonly <file> is called and os.Stat returns a mode where any of the three write bits (0o200, 0o020, 0o002) is set. The check is `info.Mode()&0222 != 0`.

Common situations: Test script creates a file (which typically defaults to writable via 0o644 or umask) then asserts it should be read-only. The file was not chmod'd to remove write bits before the assertion. Also occurs when a test expects a file to be locked/immutable but the filesystem or OS enforces different permissions.

Related errors


AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12). Data as JSON: /api/errors/405667a356de587a. Report an issue: GitHub.