{"record":{"id":"c8726d9bc0888552","repo":"Tencent/WeKnora","slug":"remote-sandbox-read-script-w","errorCode":null,"errorMessage":"remote sandbox: read script: %w","messagePattern":"remote sandbox: read script: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/sandbox/remote_sandbox.go","lineNumber":268,"sourceCode":"\t}\n}\n\n// readScriptContent resolves the script bytes to upload into the sandbox.\n// It prefers cfg.ScriptContent (populated by the security validator) and\n// falls back to reading cfg.Script from local disk.\nfunc readScriptContent(cfg *ExecuteConfig) ([]byte, error) {\n\tif cfg.ScriptContent != \"\" {\n\t\treturn []byte(cfg.ScriptContent), nil\n\t}\n\tif cfg.Script == \"\" {\n\t\treturn nil, ErrInvalidScript\n\t}\n\tcontent, err := os.ReadFile(cfg.Script)\n\tif err != nil {\n\t\tif os.IsNotExist(err) {\n\t\t\treturn nil, ErrScriptNotFound\n\t\t}\n\t\treturn nil, fmt.Errorf(\"remote sandbox: read script: %w\", err)\n\t}\n\treturn content, nil\n}\n\n// boundedExecuteContext returns a derived context with the effective timeout\n// applied. It is only used on the ephemeral path; persistent execution runs\n// under SessionBoundManager's context (which the lifecycle lock already\n// bounds).\nfunc boundedExecuteContext(parent context.Context, cfg *ExecuteConfig) (context.Context, context.CancelFunc) {\n\ttimeout := effectiveTimeout(cfg, 0)\n\tif timeout <= 0 {\n\t\treturn parent, func() {}\n\t}\n\treturn context.WithTimeout(parent, timeout)\n}\n\nfunc effectiveTimeout(cfg *ExecuteConfig, fallback time.Duration) time.Duration {\n\tif cfg != nil && cfg.Timeout > 0 {","sourceCodeStart":250,"sourceCodeEnd":286,"githubUrl":"https://github.com/Tencent/WeKnora/blob/988cbb03305e055d8ebb7d46d9ac6cc0803cd074/internal/sandbox/remote_sandbox.go#L250-L286","documentation":"readScriptContent loads the local script file from cfg.Script with os.ReadFile. Missing files map to ErrScriptNotFound, but any other read failure (permissions, I/O error, path is a directory) is wrapped with this message. It happens before anything is uploaded to the remote sandbox.","triggerScenarios":"ExecuteOnHandle path where cfg.Script exists in name but cannot be read: permission denied, file deleted between check and read, path is a directory, or disk I/O error.","commonSituations":"Scripts referenced from a mounted volume that unmounted; wrong file mode in a container; script path pointing at a directory after a refactor; filesystem full.","solutions":["Check the wrapped cause: if permission denied, chmod/chown the script to be readable","Verify cfg.Script points to a regular file, not a directory, and exists on the local filesystem","Handle ErrScriptNotFound separately — the library already distinguishes it","In containers, ensure the script is copied into the image or the volume is mounted"],"exampleFix":"// before\n// script baked into a read-only 0600 root-owned file\n// after\nif err := os.Chmod(scriptPath, 0o755); err != nil {\n    return fmt.Errorf(\"make script readable: %w\", err)\n}\nres, err := sbx.ExecuteOnHandle(ctx, handle, cfg)","handlingStrategy":"validation","validationCode":"info, err := os.Stat(cfg.Script)\nif err != nil { return err }\nif !info.Mode().IsRegular() || info.Mode().Perm()&0o400 == 0 {\n    return fmt.Errorf(\"script %s not a readable regular file\", cfg.Script)\n}","typeGuard":"func readableScript(p string) bool {\n    i, err := os.Stat(p)\n    return err == nil && i.Mode().IsRegular()\n}","tryCatchPattern":"res, err := sbx.ExecuteOnHandle(ctx, handle, cfg)\nif err != nil {\n    if errors.Is(err, sandbox.ErrScriptNotFound) { return errScriptMissing }\n    if strings.Contains(err.Error(), \"read script\") { return errScriptUnreadable }\n    return err\n}","preventionTips":["Stat the script before dispatching to the sandbox","Run workers with a user that can read mounted scripts","Verify volumes/mounts are present in containerized runners"],"tags":["go","filesystem","io","script-loading"],"backgroundTag":"file-read-permission","analyzedSha":"988cbb03305e055d8ebb7d46d9ac6cc0803cd074","analyzedAt":"2026-09-02T14:41:08.344Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}