{"record":{"id":"01ad4d45e89d3826","repo":"slimtoolkit/slim","slug":"could-not-read-command-file-q-w","errorCode":null,"errorMessage":"could not read command file %q: %w","messagePattern":"could not read command file %q: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/app/sensor/execution/standalone.go","lineNumber":101,"sourceCode":"\tencoder := json.NewEncoder(e.eventFile)\n\tencoder.SetEscapeHTML(false)\n\tevt := event.Message{Name: name}\n\tif len(data) > 0 {\n\t\tevt.Data = data[0]\n\t}\n\n\tif err := encoder.Encode(evt); err != nil {\n\t\tlog.WithError(err).Warn(\"sensor: failed dumping event\")\n\t}\n}\n\n// TODO: Make this function return a list of commands.\nfunc readCommandFile(filename string) (command.StartMonitor, error) {\n\tvar cmd command.StartMonitor\n\n\tdata, err := os.ReadFile(filename)\n\tif err != nil {\n\t\treturn cmd, fmt.Errorf(\"could not read command file %q: %w\", filename, err)\n\t}\n\tdata = bytes.Split(data, []byte(\"\\n\"))[0]\n\n\tif err := json.Unmarshal(data, &cmd); err != nil {\n\t\treturn cmd, fmt.Errorf(\"could not decode command %q: %w\", string(data), err)\n\t}\n\n\t// The instrumented image will always have the ENTRYPOINT overwritten\n\t// by the instrumentor to make the sensor the PID1 process in the monitored\n\t// container.\n\t// The original ENTRYPOINT & CMD will be preserved as part of the\n\t// `commands.json` file. However, it's also possible to override the\n\t// CMD at runtime by supplying extra args to the `docker run` (or alike)\n\t// command. Sensor needs to be able to detect this and replace the\n\t// baked in CMD with the new list of args. For that, the instrumented image's\n\t// ENTRYPOINT has to contain a special separator value `--` denoting the end\n\t// of the sensor's flags sequence. Example:\n\t//","sourceCodeStart":83,"sourceCodeEnd":119,"githubUrl":"https://github.com/slimtoolkit/slim/blob/81940d17fa112cc678e32209214bcb2355cb3004/pkg/app/sensor/execution/standalone.go#L83-L119","documentation":"readCommandFile loads the command file with os.ReadFile and returns the first line. If reading the file fails at the OS level (file absent, permission denied, path is a directory), this error wraps the os.ReadFile failure and is returned to NewStandalone.","triggerScenarios":"readCommandFile called with a filename that cannot be opened for reading: nonexistent path, wrong permissions, or path resolves to a directory.","commonSituations":"Sensor started before the orchestrator/instrumentor wrote the command file (race condition); command file path misconfigured; shared emptyDir volume not mounted.","solutions":["Confirm the command file exists at the exact path (check the wrapped ENOENT/EPERM error).","Add ordering/retry so the sensor only starts after the command file has been written.","Correct the command file path in the execution setup configuration."],"exampleFix":"// before\ncmd, err := readCommandFile(cfg.CommandFile) // ENOENT\n// after\nif _, err := os.Stat(cfg.CommandFile); err != nil {\n    return nil, fmt.Errorf(\"command file not present yet: %w\", err)\n}\ncmd, err := readCommandFile(cfg.CommandFile)","handlingStrategy":"validation","validationCode":"func waitForFile(path string, timeout time.Duration) error {\n    deadline := time.Now().Add(timeout)\n    for time.Now().Before(deadline) {\n        if fi, err := os.Stat(path); err == nil && fi.Size() > 0 {\n            return nil\n        }\n        time.Sleep(100 * time.Millisecond)\n    }\n    return fmt.Errorf(\"command file %s not ready within %s\", path, timeout)\n}","typeGuard":"func isReadFailure(err error) bool {\n    return errors.Is(err, fs.ErrNotExist) || errors.Is(err, fs.ErrPermission)\n}","tryCatchPattern":"cmd, err := readCommandFile(filename) // via NewStandalone\nif err != nil && strings.Contains(err.Error(), \"could not read command file\") {\n    // retry after checking the file exists, or fail startup with a clear message\n    return retryOrAbort(fmt.Errorf(\"command file unreadable: %w\", err))\n}","preventionTips":["Write the command file atomically (write to temp file then rename) before signaling the sensor.","Ensure the writer finishes before starting the sensor process.","Verify permissions so the sensor's uid can read the file.","Never place the command file on a lazily-mounted volume."],"tags":["filesystem","file-read","race-condition","json-command"],"backgroundTag":"file-not-found","analyzedSha":"81940d17fa112cc678e32209214bcb2355cb3004","analyzedAt":"2026-08-31T23:06:12.682Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}