{"record":{"id":"4d940faa7bf62260","repo":"larksuite/cli","slug":"read-content-safety-config-w","errorCode":null,"errorMessage":"read content-safety config: %w","messagePattern":"read content-safety config: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/security/contentsafety/config.go","lineNumber":39,"sourceCode":"\tAllowlist []string\n\tRules     []rule\n}\n\ntype rawConfig struct {\n\tAllowlist []string  `json:\"allowlist\"`\n\tRules     []rawRule `json:\"rules\"`\n}\n\ntype rawRule struct {\n\tID      string `json:\"id\"`\n\tPattern string `json:\"pattern\"`\n}\n\nfunc LoadConfig(configDir string) (*Config, error) {\n\tpath := filepath.Join(configDir, configFileName)\n\tdata, err := vfs.ReadFile(path)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"read content-safety config: %w\", err)\n\t}\n\tvar raw rawConfig\n\tif err := json.Unmarshal(data, &raw); err != nil {\n\t\treturn nil, fmt.Errorf(\"parse content-safety config: %w\", err)\n\t}\n\trules := make([]rule, 0, len(raw.Rules))\n\tfor _, r := range raw.Rules {\n\t\tcompiled, err := regexp.Compile(r.Pattern)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"compile rule %q pattern: %w\", r.ID, err)\n\t\t}\n\t\trules = append(rules, rule{ID: r.ID, Pattern: compiled})\n\t}\n\treturn &Config{Allowlist: raw.Allowlist, Rules: rules}, nil\n}\n\nfunc EnsureDefaultConfig(configDir string, errOut io.Writer) error {\n\tpath := filepath.Join(configDir, configFileName)","sourceCodeStart":21,"sourceCodeEnd":57,"githubUrl":"https://github.com/larksuite/cli/blob/7fd6ef3c07182257ce776cdc5a614e122d5bd4b3/internal/security/contentsafety/config.go#L21-L57","documentation":"LoadConfig reads the content-safety config file from the given configDir and wraps any read failure from vfs.ReadFile. It means the config file could not be read — usually because it does not exist yet, or permissions/path issues prevent reading it.","triggerScenarios":"Calling LoadConfig(configDir) when <configDir>/content-safety config file is missing, unreadable (permissions), or configDir is wrong. Also called indirectly through loadOrCreate on CLI startup.","commonSituations":"Fresh checkout or new machine where EnsureDefaultConfig was never run; LARKSUITE_CLI_CONFIG_DIR pointing at a nonexistent directory; restrictive file permissions on the config file.","solutions":["Call EnsureDefaultConfig(configDir, errOut) first to create the default file, or use loadOrCreate which does this","Verify configDir points to the directory containing the config file (check LARKSUITE_CLI_CONFIG_DIR)","Check file permissions on the config file (expected 0600) and directory (0700)"],"exampleFix":"// before\nconfig, err := contentsafety.LoadConfig(dir) // fails: file missing\n// after\nif err := contentsafety.EnsureDefaultConfig(dir, os.Stderr); err != nil { return err }\nconfig, err := contentsafety.LoadConfig(dir)","handlingStrategy":"fallback","validationCode":"path := filepath.Join(configDir, \"content-safety-config.json\") // see configFileName\nif _, err := os.Stat(path); errors.Is(err, os.ErrNotExist) {\n\t// file missing — create defaults first\n}","typeGuard":null,"tryCatchPattern":"config, err := contentsafety.LoadConfig(dir)\nif err != nil {\n\tif strings.Contains(err.Error(), \"read content-safety config\") && errors.Is(err, os.ErrNotExist) {\n\t\tif e := contentsafety.EnsureDefaultConfig(dir, os.Stderr); e != nil { return e }\n\t\tconfig, err = contentsafety.LoadConfig(dir)\n\t}\n\tif err != nil { return err }\n}","preventionTips":["Always run EnsureDefaultConfig (or loadOrCreate) before LoadConfig","Set LARKSUITE_CLI_CONFIG_DIR to an existing writable directory","Check file permissions (0600 file, 0700 dir) when provisioning environments"],"tags":["config","filesystem","content-safety"],"backgroundTag":"config-file-not-found","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"}