{"record":{"id":"355cd5b35e15d54e","repo":"golang/go","slug":"s-exists-but-is-not-executable","errorCode":null,"errorMessage":"%s exists but is not executable","messagePattern":"(.+?) exists but is not executable","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cmd/internal/script/cmds.go","lineNumber":617,"sourceCode":"\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{\n\t\t\tSummary: \"find lines in a file that match a pattern\",\n\t\t\tArgs:    matchUsage + \" file\",\n\t\t\tDetail: []string{","sourceCodeStart":599,"sourceCodeEnd":635,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/cmd/internal/script/cmds.go#L599-L635","documentation":"Thrown by the exists command (with -exec flag) in the Go test script framework when a file exists but has no execute permission bits set (mode & 0o111 == 0). This check is skipped on Windows (runtime.GOOS != \"windows\"). The command asserts that files should be executable.","triggerScenarios":"exists -exec <file> is called on a non-Windows platform and os.Stat returns a mode where none of the three execute bits (0o100, 0o010, 0o001) are set. The check is `info.Mode()&0111 == 0`.","commonSituations":"Test script builds or copies a binary but doesn't set the executable bit, then asserts it should be executable. Common after `cp` without preserving mode, or when creating a file from content without chmod. Also happens with cross-compiled binaries that haven't been chmod'd.","solutions":["Run `chmod 0755 file` in the script before the exists -exec check.","Use `cp -perm=0755` or ensure the build step produces an executable-mode file.","On Windows this check is skipped; ensure you're testing on the intended platform."],"exampleFix":"// Before:\n// exists -exec mybin\n//\n// After (add chmod first):\n// chmod 0755 mybin\n// exists -exec mybin","handlingStrategy":"validation","validationCode":"// Ensure file is executable before asserting exists -exec:\n// In the test script:\n// chmod 0755 mybin\n// exists -exec mybin\n\n// Programmatic check:\nfunc ensureExecutable(path string) error {\n    info, err := os.Stat(path)\n    if err != nil { return err }\n    if runtime.GOOS != \"windows\" && info.Mode() & 0111 == 0 {\n        return os.Chmod(path, info.Mode()|0100)\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always chmod binaries to include execute bits before exists -exec assertions.","Use 0755 for executables in test scripts.","Ensure cp or build steps preserve or set executable permissions."],"tags":["script","test-framework","exists","permissions","executable","assertion","go-compiler-internal"],"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T12:17:08.281Z"}