{"record":{"id":"f0a791839f9d8597","repo":"github/github-mcp-server","slug":"provide-either-visible-fields-or-visible-field","errorCode":null,"errorMessage":"provide either 'visible_fields' or 'visible_field_names', not both","messagePattern":"provide either 'visible_fields' or 'visible_field_names', not both","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/github/projects.go","lineNumber":2055,"sourceCode":"}\n\nfunc projectViewVisibleFieldsInput(ctx context.Context, gqlClient *githubv4.Client, args map[string]any, owner, ownerType string, projectNumber int) (*ProjectV2ViewConfigurationInput, error) {\n\t_, hasVisibleFields := args[\"visible_fields\"]\n\t_, hasVisibleFieldNames := args[\"visible_field_names\"]\n\tif !hasVisibleFields && !hasVisibleFieldNames {\n\t\treturn nil, nil\n\t}\n\n\tdatabaseIDs, err := OptionalBigIntArrayParam(args, \"visible_fields\")\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tnames, err := OptionalStringArrayParam(args, \"visible_field_names\")\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif len(databaseIDs) > 0 && len(names) > 0 {\n\t\treturn nil, errors.New(\"provide either 'visible_fields' or 'visible_field_names', not both\")\n\t}\n\tif len(databaseIDs) == 0 && len(names) == 0 {\n\t\treturn &ProjectV2ViewConfigurationInput{VisibleFieldIDs: []githubv4.ID{}}, nil\n\t}\n\n\tall, err := listAllProjectFields(ctx, gqlClient, owner, ownerType, projectNumber)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar resolved []ResolvedField\n\tif len(names) > 0 {\n\t\tresolved, err = resolveFieldsByName(all, owner, projectNumber, names, \"visible_fields\")\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t} else {\n\t\tbyDatabaseID := make(map[int64]ResolvedField, len(all))","sourceCodeStart":2037,"sourceCodeEnd":2073,"githubUrl":"https://github.com/github/github-mcp-server/blob/0ea1f775a7c73eff1bd2e25904d01136756bbfe2/pkg/github/projects.go#L2037-L2073","documentation":"Third guard of validateBlamePath for get_file_blame: the path is split on '/' and rejected if any segment equals \"..\". This blocks parent-directory traversal before any network call. GitHub's blame would simply find no match for such a path, so the server rejects it locally with 'path must not contain '..' segments'.","triggerScenarios":"Passing \"docs/../src/main.go\" or \"../other/file.go\"; paths produced by filepath.Join with user input containing '..'; normalizing a path that escapes the repository root.","commonSituations":"Client code combining user-supplied relative paths with '..' components; converting between absolute local paths and repo-relative ones without cleaning; LLM callers echoing filesystem-style paths.","solutions":["Resolve and clean the path first, then re-express it relative to the repository root","Reject user input containing '..' before it reaches the tool","Use the final normalized path (e.g. \"src/main.go\") directly"],"exampleFix":"// before\n{\"owner\":\"octocat\",\"repo\":\"Hello-World\",\"path\":\"docs/../src/main.go\"}\n\n// after\n{\"owner\":\"octocat\",\"repo\":\"Hello-World\",\"path\":\"src/main.go\"}","handlingStrategy":"validation","validationCode":"func hasTraversal(p string) bool {\n\treturn slices.Contains(strings.Split(p, \"/\"), \"..\")\n}","typeGuard":"func isBlamePathError(err error) bool {\n\treturn err != nil && strings.HasPrefix(err.Error(), \"path must\")\n}","tryCatchPattern":"if hasTraversal(path) {\n\tclean, err := filepath.Rel(repoRoot, filepath.Join(repoRoot, path))\n\tif err != nil || hasTraversal(clean) {\n\t\treturn nil, fmt.Errorf(\"unresolvable path: %s\", path)\n\t}\n\tpath = clean\n}\nres, _, err := callGetFileBlame(ctx, buildArgs(owner, repo, path))","preventionTips":["Always resolve user paths against the repo root, then re-express relatively","Reject '..' in untrusted input before it reaches any tool","Prefer storing canonical repo-relative paths over composing them at call time","Mirror the server's split-on-slash segment check client-side"],"tags":["go","validation","path-traversal","blame"],"backgroundTag":null,"analyzedSha":"0ea1f775a7c73eff1bd2e25904d01136756bbfe2","analyzedAt":"2026-08-15T18:10:19.804Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}