{"record":{"id":"3eaa88b32d21f8ee","repo":"larksuite/cli","slug":"parse-content-safety-config-w","errorCode":null,"errorMessage":"parse content-safety config: %w","messagePattern":"parse content-safety config: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/security/contentsafety/config.go","lineNumber":43,"sourceCode":"type 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)\n\tif _, err := vfs.Stat(path); err == nil {\n\t\treturn nil\n\t}\n\tif err := vfs.MkdirAll(configDir, 0700); err != nil {","sourceCodeStart":25,"sourceCodeEnd":61,"githubUrl":"https://github.com/larksuite/cli/blob/7fd6ef3c07182257ce776cdc5a614e122d5bd4b3/internal/security/contentsafety/config.go#L25-L61","documentation":"LoadConfig read the content-safety config file successfully but json.Unmarshal rejected it - the file exists yet is not the expected {allowlist, rules:[{id,pattern}]} JSON shape; the wrapped error names the syntax position.","triggerScenarios":"Calling LoadConfig when the config file contains malformed JSON (syntax errors), was truncated mid-write, or has a top-level shape that cannot unmarshal into rawConfig (e.g. an array instead of an object).","commonSituations":"Hand-editing the config and introducing a syntax error (trailing comma, missing quote); a partially written file from a crashed process; accidental overwrite of the config with logs or HTML (captive portal).","solutions":["Run the file through a JSON linter (jq or python -m json.tool) to find the syntax error","Restore the default config: delete the file and let EnsureDefaultConfig recreate it","Fix the JSON structure to match rawConfig: {\"allowlist\": [...], \"rules\": [{\"id\":..., \"pattern\":...}]}"],"exampleFix":"// before\n{ \"rules\": [ {\"id\": \"a\", \"pattern\": \"x\",} ] }  // trailing comma\n// after\n{ \"rules\": [ {\"id\": \"a\", \"pattern\": \"x\"} ] }","handlingStrategy":"fallback","validationCode":"if err := json.Valid(data); !err {\n\treturn fmt.Errorf(\"config file contains invalid JSON\")\n}","typeGuard":null,"tryCatchPattern":"config, err := contentsafety.LoadConfig(dir)\nif err != nil {\n\tif strings.Contains(err.Error(), \"parse content-safety config\") {\n\t\t// back up the broken file, then regenerate defaults\n\t\tos.Rename(path, path+\".bak\")\n\t\tcontentsafety.EnsureDefaultConfig(dir, os.Stderr)\n\t\tconfig, err = contentsafety.LoadConfig(dir)\n\t}\n\tif err != nil { return err }\n}","preventionTips":["Validate config with jq/python before saving edits","Never hand-write JSON without a linter","Keep backups before editing config files","Restore defaults rather than fighting a broken file"],"tags":["config","json","content-safety","parse-error"],"backgroundTag":"config-parse-error","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"}