{"record":{"id":"405667a356de587a","repo":"golang/go","slug":"s-exists-but-is-writable","errorCode":null,"errorMessage":"%s exists but is writable","messagePattern":"(.+?) exists but is writable","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cmd/internal/script/cmds.go","lineNumber":614,"sourceCode":"\t\t\t\tcase \"-exec\":\n\t\t\t\t\texec = true\n\t\t\t\t\targs = args[1:]\n\t\t\t\tdefault:\n\t\t\t\t\tbreak loop\n\t\t\t\t}\n\t\t\t}\n\t\t\tif len(args) == 0 {\n\t\t\t\treturn nil, ErrUsage\n\t\t\t}\n\n\t\t\tfor _, file := range args {\n\t\t\t\tfile = s.Path(file)\n\t\t\t\tinfo, err := os.Stat(file)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, err\n\t\t\t\t}\n\t\t\t\tif readonly && info.Mode()&0222 != 0 {\n\t\t\t\t\treturn nil, fmt.Errorf(\"%s exists but is writable\", file)\n\t\t\t\t}\n\t\t\t\tif exec && runtime.GOOS != \"windows\" && info.Mode()&0111 == 0 {\n\t\t\t\t\treturn nil, fmt.Errorf(\"%s exists but is not executable\", file)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn nil, nil\n\t\t})\n}\n\n// Grep checks that file content matches a regexp.\n// Like stdout/stderr and unlike Unix grep, it accepts Go regexp syntax.\n//\n// Grep does not modify the State's stdout or stderr buffers.\n// (Its output goes to the script log, not stdout.)\nfunc Grep() Cmd {\n\treturn Command(\n\t\tCmdUsage{","sourceCodeStart":596,"sourceCodeEnd":632,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/cmd/internal/script/cmds.go#L596-L632","documentation":"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.","triggerScenarios":"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`.","commonSituations":"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.","solutions":["Run `chmod 0444 file` or `chmod 0555 file` in the script before the exists -readonly check.","Verify that the file creation step is followed by an explicit chmod to remove write bits.","Check that no prior step re-adds write permissions after the chmod."],"exampleFix":"// Before:\n// exists -readonly file.txt\n//\n// After (add chmod first):\n// chmod 0444 file.txt\n// exists -readonly file.txt","handlingStrategy":"validation","validationCode":"// Ensure file is read-only before asserting exists -readonly:\n// In the test script:\n// chmod 0444 file.txt\n// exists -readonly file.txt\n\n// Programmatic check:\nfunc ensureReadOnly(path string) error {\n    info, err := os.Stat(path)\n    if err != nil { return err }\n    if info.Mode() & 0222 != 0 {\n        return os.Chmod(path, info.Mode() & ^fs.FileMode(0222))\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always chmod files to remove write bits before exists -readonly assertions.","Use 0444 for files or 0555 for directories/executables in test scripts.","Verify that no prior step re-adds write permissions."],"tags":["script","test-framework","exists","permissions","readonly","assertion","go-compiler-internal"],"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T12:17:08.281Z"}