{"record":{"id":"73e37321de041d09","repo":"charmbracelet/crush","slug":"interpreter-q-not-found-and-q-not-in-path","errorCode":null,"errorMessage":"interpreter %q not found and %q not in PATH","messagePattern":"interpreter %q not found and %q not in PATH","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/shell/dispatch.go","lineNumber":246,"sourceCode":"\tif statErr == nil {\n\t\treturn path, nil\n\t}\n\tif !errors.Is(statErr, fs.ErrNotExist) {\n\t\treturn \"\", statErr\n\t}\n\n\tbase := filepath.Base(path)\n\tif base == \"\" || base == path && !strings.ContainsAny(path, `/\\`) {\n\t\t// Already a bare name — just do a PATH lookup.\n\t\tresolved, err := exec.LookPath(path)\n\t\tif err != nil {\n\t\t\treturn \"\", fmt.Errorf(\"interpreter %q not found in PATH\", path)\n\t\t}\n\t\treturn resolved, nil\n\t}\n\tresolved, err := exec.LookPath(base)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"interpreter %q not found and %q not in PATH\", path, base)\n\t}\n\tslog.Debug(\"Shebang interpreter not found; falling back to PATH\",\n\t\t\"requested\", path, \"resolved\", resolved)\n\treturn resolved, nil\n}\n\n// shebang captures the parsed `#!` line. interpreter is the program to\n// invoke; args is the list of extra arguments to pass before the script\n// path. The kernel's single-arg semantics (for literal paths and for env\n// without `-S`) is encoded by returning a single-element args slice\n// containing the un-tokenized remainder.\ntype shebang struct {\n\tinterpreter string\n\targs        []string\n}\n\n// parseShebang extracts the interpreter invocation from probe. It tolerates\n// CRLF line endings and a single leading space between `#!` and the path.","sourceCodeStart":228,"sourceCodeEnd":264,"githubUrl":"https://github.com/charmbracelet/crush/blob/7944b8e52225d8805e31eacbf7ef24856b0dfb7a/internal/shell/dispatch.go#L228-L264","documentation":"resolveInterpreter reports that the shebang's literal interpreter path does not exist AND its basename cannot be found on PATH. This is the two-part variant of the bare-name lookup failure: the resolver tried os.Stat on the literal path (got fs.ErrNotExist), then exec.LookPath on the basename, and both failed.","triggerScenarios":"A script's shebang uses a full path (contains '/' or '\\'), e.g. `#!/usr/local/bin/python3`; os.Stat returns fs.ErrNotExist (so EACCES etc. are surfaced elsewhere), and exec.LookPath(\"python3\") also fails. Raised by dispatchShebang for every such script.","commonSituations":"Scripts copied between machines where the interpreter lives at different paths; Docker images without /usr/local/bin/python3; Windows hosts lacking any PATH-resolvable bash for `#!/bin/bash`; uninstalling an interpreter after scripts referencing it were authored.","solutions":["Install the interpreter so the shebang path exists, or place its basename on PATH.","Edit the shebang to reference an interpreter that exists on the current machine.","For portability, use `#!/usr/bin/env <name>` form so the resolver can PATH-lookup the name directly.","On Windows, install Git for Windows and add its usr/bin (bash.exe) to PATH."],"exampleFix":"// before\n#!/usr/local/bin/python3\nprint('hi')\n// after\n#!/usr/bin/env python3\nprint('hi')","handlingStrategy":"validation","validationCode":"interp := \"/usr/local/bin/python3\"\nif _, err := os.Stat(interp); errors.Is(err, fs.ErrNotExist) {\n    if _, err := exec.LookPath(filepath.Base(interp)); err != nil {\n        // neither path nor PATH has it — fix environment first\n    }\n}","typeGuard":null,"tryCatchPattern":"var pe *fs.PathError\nif errors.As(err, &pe) || strings.Contains(err.Error(), \"not found and\") {\n    // surface a friendly 'install <interpreter>' message\n}","preventionTips":["Lint shebangs in CI against a matrix of target machines.","Avoid absolute interpreter paths in shared scripts; use env form.","Document required interpreters per project and verify at bootstrap.","Keep interpreter installs and PATH in infrastructure-as-code."],"tags":["shell","shebang","path-lookup","interpreter"],"backgroundTag":"interpreter-not-found-in-path","analyzedSha":"7944b8e52225d8805e31eacbf7ef24856b0dfb7a","analyzedAt":"2026-08-29T12:48:59.079Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}