github/github-mcp-server · error

response did not include the deleted project view

Error message

response did not include the deleted project view

What it means

Fourth guard of validateBlamePath for get_file_blame: any rune below 0x20 (space is 0x20 and allowed) or equal to 0x7f (DEL) is rejected. Control characters would corrupt the GraphQL variable or match nothing in the git tree, so the server fails fast with 'path must not contain control characters'. Note the check iterates runes, so valid UTF-8 multibyte characters pass.

Source

Thrown at pkg/github/projects.go:2300

		return utils.NewToolResultError(fmt.Sprintf("%s: response did not include a project view", ProjectViewUpdateFailedError)), nil, nil
	}
	return MarshalledTextResult(convertToMinimalProjectView(mutation.UpdateProjectV2View.ProjectV2View)), nil, nil
}

func deleteProjectViewByID(ctx context.Context, gqlClient *githubv4.Client, viewID githubv4.ID) error {
	input := DeleteProjectV2ViewInput{ViewID: viewID}
	var mutation struct {
		DeleteProjectV2View struct {
			ProjectV2View struct {
				ID githubv4.ID
			} `graphql:"projectV2View"`
		} `graphql:"deleteProjectV2View(input: $input)"`
	}
	if err := gqlClient.Mutate(ctx, &mutation, input, nil); err != nil {
		return err
	}
	if id := mutation.DeleteProjectV2View.ProjectV2View.ID; id == nil || id == "" {
		return errors.New("response did not include the deleted project view")
	}
	return nil
}

func deleteProjectView(ctx context.Context, gqlClient *githubv4.Client, args map[string]any, owner, ownerType string, projectNumber int) (*mcp.CallToolResult, any, error) {
	viewID, err := RequiredParam[string](args, "view_id")
	if err != nil {
		return utils.NewToolResultError(err.Error()), nil, nil
	}
	if _, err := verifyProjectViewParent(ctx, gqlClient, viewID, owner, ownerType, projectNumber); err != nil {
		return utils.NewToolResultError(fmt.Sprintf("%s: %v", ProjectViewDeleteFailedError, err)), nil, nil
	}
	if err := deleteProjectViewByID(ctx, gqlClient, githubv4.ID(viewID)); err != nil {
		return utils.NewToolResultError(fmt.Sprintf("%s: %v", ProjectViewDeleteFailedError, err)), nil, nil
	}
	return MarshalledTextResult(map[string]string{"deleted_view_id": viewID}), nil, nil
}

View on GitHub (pinned to 0ea1f775a7)

Solutions

  1. Trim whitespace and control runes from the path before sending
  2. When paths come from files or pipes, strip the trailing newline explicitly
  3. Add a client-side scan for bytes < 0x20 and 0x7f before the tool call

Example fix

// before: trailing newline from a shell pipeline
{"path":"src/main.go\n"}

// after
{"path":"src/main.go"}
Defensive patterns

Strategy: validation

Validate before calling

func hasControlRunes(p string) bool {
	for _, r := range p {
		if r < 0x20 || r == 0x7f {
			return true
		}
	}
	return false
}

Type guard

func isBlamePathError(err error) bool {
	return err != nil && strings.HasPrefix(err.Error(), "path must")
}

Try / catch

path = strings.TrimFunc(path, func(r rune) bool { return r < 0x20 || r == 0x7f })
if hasControlRunes(path) {
	return nil, fmt.Errorf("path contains control characters")
}
res, _, err := callGetFileBlame(ctx, buildArgs(owner, repo, path))

Prevention

When it happens

Trigger: Paths containing '\t', '\n', '\r', or DEL - typically from copy-paste with a trailing newline, string building with embedded escapes, or terminal input that captures control keystrokes.

Common situations: Piping paths from shell commands that append newlines; splitting file lists on the wrong delimiter; LLM-generated arguments with literal escape sequences; editors inserting BOM-like characters (0x00-0x1f range).

Related errors


AI-assisted analysis of github/github-mcp-server@0ea1f775a7 (2026-08-15). Data as JSON: /api/errors/f86ab7f5ef645c28. Report an issue: GitHub.