{"record":{"id":"e8de845ea1d2dcc9","repo":"larksuite/cli","slug":"suite-description-keyword-suffix-is-missing","errorCode":null,"errorMessage":"suite description keyword suffix is missing","messagePattern":"suite description keyword suffix is missing","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/skillscheck/layout.go","lineNumber":153,"sourceCode":"\t\t}\n\t\tcontent = line.ReplaceAllString(content, \"\")\n\t}\n\n\tfor _, name := range target {\n\t\tif len(routeLine(name).FindAllStringIndex(content, -1)) != 1 {\n\t\t\treturn \"\", fmt.Errorf(\"cropped suite route for %s is missing or duplicated\", name)\n\t\t}\n\t}\n\n\tkeywords := suiteKeywords(content)\n\tstart := strings.Index(content, suiteDescriptionPrefix)\n\tif start < 0 {\n\t\treturn \"\", fmt.Errorf(\"suite description prefix is missing\")\n\t}\n\tvalueStart := start + len(suiteDescriptionPrefix)\n\tvalueEndOffset := strings.Index(content[valueStart:], suiteDescriptionSuffix)\n\tif valueEndOffset < 0 {\n\t\treturn \"\", fmt.Errorf(\"suite description keyword suffix is missing\")\n\t}\n\tvalueEnd := valueStart + valueEndOffset\n\tcontent = content[:valueStart] + strings.Join(keywords, \"、\") + content[valueEnd:]\n\treturn content, nil\n}\n\nfunc suiteKeywords(content string) []string {\n\trouteLine := regexp.MustCompile(`(?m)^- [^\\n（]+(?:（([^）\\n]*)）)?:`)\n\tseen := map[string]bool{}\n\tkeywords := []string{}\n\tfor _, match := range routeLine.FindAllStringSubmatch(content, -1) {\n\t\tif len(match) < 2 || match[1] == \"\" {\n\t\t\tcontinue\n\t\t}\n\t\tfor _, keyword := range strings.Split(match[1], \"、\") {\n\t\t\tkeyword = strings.TrimSpace(keyword)\n\t\t\tif keyword != \"\" && !seen[keyword] {\n\t\t\t\tseen[keyword] = true","sourceCodeStart":135,"sourceCodeEnd":171,"githubUrl":"https://github.com/larksuite/cli/blob/7fd6ef3c07182257ce776cdc5a614e122d5bd4b3/internal/skillscheck/layout.go#L135-L171","documentation":"Guard in cropSuiteRoutes: the suite SKILL.md description does not contain the expected keyword suffix delimiter, so the keyword list cannot be rewritten for the cropped skill set.","triggerScenarios":"Thrown at internal/skillscheck/layout.go:153 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Ensure the suite description keeps its terminating keyword suffix so the list stays parseable"],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"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"}