{"record":{"id":"a1e59c13659d93db","repo":"chenhg5/cc-connect","slug":"project-q-not-found","errorCode":null,"errorMessage":"project %q not found","messagePattern":"project %q not found","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"config/config.go","lineNumber":1851,"sourceCode":"func GetProjectProviders(projectName string) ([]ProviderConfig, string, error) {\n\tif ConfigPath == \"\" {\n\t\treturn nil, \"\", fmt.Errorf(\"config path not set\")\n\t}\n\tdata, err := os.ReadFile(ConfigPath)\n\tif err != nil {\n\t\treturn nil, \"\", fmt.Errorf(\"read config: %w\", err)\n\t}\n\tcfg := &Config{}\n\tif err := toml.Unmarshal(data, cfg); err != nil {\n\t\treturn nil, \"\", fmt.Errorf(\"parse config: %w\", err)\n\t}\n\tfor _, p := range cfg.Projects {\n\t\tif p.Name == projectName {\n\t\t\tactive, _ := p.Agent.Options[\"provider\"].(string)\n\t\t\treturn p.Agent.Providers, active, nil\n\t\t}\n\t}\n\treturn nil, \"\", fmt.Errorf(\"project %q not found\", projectName)\n}\n\n// FeishuCredentialUpdateOptions controls how Feishu/Lark platform credentials\n// are written back into config.toml for a specific project.\ntype FeishuCredentialUpdateOptions struct {\n\tProjectName       string // required\n\tPlatformIndex     int    // 1-based index among feishu/lark platforms in the project; 0 = first\n\tPlatformType      string // optional target type: \"feishu\" or \"lark\"; empty keeps existing type\n\tAppID             string // required\n\tAppSecret         string // required\n\tOwnerOpenID       string // optional owner id from onboarding flow\n\tSetAllowFromEmpty bool   // when true, seed/append allow_from with OwnerOpenID while preserving \"*\"\n}\n\n// EnsureProjectWithFeishuOptions controls project auto-provisioning for Feishu/Lark setup.\ntype EnsureProjectWithFeishuOptions struct {\n\tProjectName      string // required\n\tPlatformType     string // optional: \"feishu\" or \"lark\", default \"feishu\"","sourceCodeStart":1833,"sourceCodeEnd":1869,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/config/config.go#L1833-L1869","documentation":"After successfully loading and parsing the config, GetProjectProviders scans cfg.Projects for one whose Name equals projectName; if none matches it returns (nil, \"\", fmt.Errorf(\"project %q not found\", projectName)). Exact, case-sensitive string match on the project's configured name.","triggerScenarios":"Calling config.GetProjectProviders(\"name\") where no [[projects]] entry has that exact Name — wrong project name, project defined in a different config file, or casing mismatch.","commonSituations":"Typos or different naming between a UI and config.toml; querying a project that was removed or renamed; multi-config setups where ConfigPath points to a file lacking the project; automation passing an ID instead of the display name.","solutions":["Enumerate projects in config.toml (or via the app's project list command) and use the exact Name value.","Check ConfigPath points to the config file that actually contains the project.","Fix casing — the comparison is exact equality, not case-insensitive.","Handle the error to prompt the user to create the project if it legitimately doesn't exist."],"exampleFix":"// before\np, _, err := config.GetProjectProviders(\"Demo\") // stored as \"demo\" -> not found\n// after\nprojects, _ := config.ListProjects()\nif !slices.ContainsFunc(projects, func(p config.ProjectConfig) bool { return p.Name == \"demo\" }) {\n    return fmt.Errorf(\"project %q not configured\", \"demo\")\n}\np, _, err := config.GetProjectProviders(\"demo\")","handlingStrategy":"validation","validationCode":"projects, err := config.ListProjects()\nif err != nil { return err }\nif !slices.ContainsFunc(projects, func(p config.ProjectConfig) bool { return p.Name == projectName }) {\n    return fmt.Errorf(\"project %q not configured\", projectName)\n}","typeGuard":"func projectExists(name string) bool {\n    projects, err := config.ListProjects()\n    if err != nil { return false }\n    return slices.ContainsFunc(projects, func(p config.ProjectConfig) bool { return p.Name == name })\n}","tryCatchPattern":"providers, active, err := config.GetProjectProviders(project)\nif err != nil {\n    if strings.Contains(err.Error(), \"not found\") {\n        return fmt.Errorf(\"unknown project %q — run 'project list' to see valid names\", project)\n    }\n    return err\n}","preventionTips":["Copy project names exactly from config.toml or the list command.","Watch for renames: update callers when a project's Name changes.","Confirm ConfigPath targets the config containing the project.","Remember matching is case-sensitive exact equality."],"tags":["config","projects","not-found"],"backgroundTag":"resource-not-found","analyzedSha":"4000b2338aa6e850c99df54f8b0ed6ed7460b401","analyzedAt":"2026-09-06T11:45:09.575Z","contentChangedAt":"2026-09-06T11:45:09.575Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}