{"record":{"id":"8156fe27a4925046","repo":"larksuite/cli","slug":"failed-to-read-proxy-plugin-config-q-w","errorCode":null,"errorMessage":"failed to read proxy plugin config %q: %w","messagePattern":"failed to read proxy plugin config %q: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/transport/config.go","lineNumber":108,"sourceCode":"\t\t\tloadErr = fmt.Errorf(\"failed to stat proxy plugin config %q: %w\", p, err)\n\t\t\treturn\n\t\t}\n\t\t// Security hardening: this config dictates where ALL outbound CLI traffic\n\t\t// egresses and which extra CA is trusted, so a file another local user or\n\t\t// process can tamper with (symlink, foreign owner, group/world-writable)\n\t\t// could redirect credential traffic. Audit it the same way the CA file is.\n\t\tsafePath, err := binding.AssertSecurePath(binding.AuditParams{\n\t\t\tTargetPath:            p,\n\t\t\tLabel:                 ConfigFileName,\n\t\t\tAllowReadableByOthers: true, // config is not a secret; only writability/owner/symlink matter\n\t\t})\n\t\tif err != nil {\n\t\t\tloadErr = fmt.Errorf(\"unsafe proxy plugin config %q: %w\", p, err)\n\t\t\treturn\n\t\t}\n\t\tb, err := vfs.ReadFile(safePath)\n\t\tif err != nil {\n\t\t\tloadErr = fmt.Errorf(\"failed to read proxy plugin config %q: %w\", p, err)\n\t\t\treturn\n\t\t}\n\t\tvar fileCfg Config\n\t\tif err := json.Unmarshal(b, &fileCfg); err != nil {\n\t\t\tloadErr = fmt.Errorf(\"invalid proxy plugin config %q: %w\", p, err)\n\t\t\treturn\n\t\t}\n\n\t\t// Merge: file base + env overrides.\n\t\tif cfg == nil {\n\t\t\tcfg = &fileCfg\n\t\t} else {\n\t\t\t*cfg = fileCfg\n\t\t\tapplyEnvOverrides(cfg)\n\t\t}\n\t\tloadCfg = cfg\n\t})\n\treturn loadCfg, loadErr","sourceCodeStart":90,"sourceCodeEnd":126,"githubUrl":"https://github.com/larksuite/cli/blob/7fd6ef3c07182257ce776cdc5a614e122d5bd4b3/internal/transport/config.go#L90-L126","documentation":"transport.Load returns this error when the proxy plugin config file passed its stat and security audit, but vfs.ReadFile fails. Unlike the stat error (437), this occurs after the file was confirmed present and safe, so the failure is typically a race (file removed/permissions changed between stat and read), an access-control change, or an underlying filesystem error. It wraps the OS error for diagnosis.","triggerScenarios":"vfs.ReadFile(safePath) on the audited ~/.lark-cli/proxy_config.json returns an error: the file was deleted between Stat and Read, permissions were tightened in between, an ACL/SELinux/AppArmor policy denies the read, or a network home directory hit an I/O error.","commonSituations":"Concurrent cleanup scripts or another session removing ~/.lark-cli files while the CLI starts; SELinux/AppArmor denials in hardened containers despite POSIX permissions looking fine; EFS/NFS home mounts with transient I/O failures; backup agents locking files on Windows-style mounts.","solutions":["Re-run the command — transient races/NFS errors usually clear","Check the wrapped OS error for the specific cause (ENOENT vs EACCES vs I/O error)","Verify SELinux/AppArmor isn't blocking reads of the config dir (check audit logs; restorecon ~/.lark-cli if mislabeled)","If the file keeps disappearing, identify the cleanup process or recreate the config with correct owner and 644 permissions"],"exampleFix":"// before\nlark-cli ... -> failed to read proxy plugin config: permission denied\n\n// after\nchmod u+r ~/.lark-cli/proxy_config.json  # or restorecon ~/.lark-cli on SELinux systems","handlingStrategy":"retry","validationCode":"// confirm readable immediately before invoking the CLI\np := filepath.Join(core.GetConfigDir(), transport.ConfigFileName)\nif f, err := os.Open(p); err != nil {\n    return fmt.Errorf(\"proxy config not readable: %w\", err)\n} else {\n    f.Close()\n}","typeGuard":null,"tryCatchPattern":"var cfg *transport.Config\nvar err error\nfor i := 0; i < 3; i++ {\n    cfg, err = transport.Load()\n    if err == nil || !strings.Contains(err.Error(), \"failed to read proxy plugin config\") {\n        break\n    }\n    time.Sleep(200 * time.Millisecond) // transient race / NFS hiccup\n}","preventionTips":["Prevent cleanup agents or concurrent sessions from deleting ~/.lark-cli files while the CLI runs","Check SELinux/AppArmor policies that deny reads despite POSIX perms (use restorecon / adjust policy)","Keep home dirs off unreliable NFS/EFS mounts or retry on transient I/O errors","Recreate the config with owner=read (chmod 644) if it intermittently loses permissions"],"tags":["filesystem","proxy-config","read-error","race-condition"],"backgroundTag":"config-file-unreadable","analyzedSha":"7fd6ef3c07182257ce776cdc5a614e122d5bd4b3","analyzedAt":"2026-09-04T21:17:44.649Z","contentChangedAt":"2026-09-04T21:17:44.649Z","schemaVersion":2},"datasetVersion":"2026-09-12T02:17:10.037Z"}