googleapis/mcp-toolbox · warning

failed to marshal credentials: %v

Error message

failed to marshal credentials: %v

What it means

This error is returned by doLogin when json.Marshal cannot serialize the login credentials payload into JSON before POSTing it to the Dgraph /login endpoint. In practice this is nearly unreachable because creds is a plain struct with string fields, which json.Marshal can always encode; the %v verb wraps the underlying marshal error. It functions as a defensive guard in the login request-building sequence.

Source

Thrown at internal/sources/dgraph/dgraph.go:295

	return hc.doLogin(credentials)
}

func (hc *DgraphClient) loginWithToken() error {
	credentials := map[string]interface{}{
		"refreshJWT": hc.RefreshToken,
		"namespace":  hc.Namespace,
	}
	return hc.doLogin(credentials)
}

func (hc *DgraphClient) doLogin(creds map[string]interface{}) error {
	url, err := getUrl(hc.baseUrl, "/login", nil)
	if err != nil {
		return err
	}
	payload, err := json.Marshal(creds)
	if err != nil {
		return fmt.Errorf("failed to marshal credentials: %v", err)
	}
	req, err := http.NewRequest(http.MethodPost, url, bytes.NewBuffer(payload))
	if err != nil {
		return fmt.Errorf("error building req for endpoint [%v] : %v", url, err)
	}
	req.Header.Add("Content-Type", "application/json")
	if hc.apiKey != "" {
		req.Header.Set("Dg-Auth", hc.apiKey)
	}

	resp, err := hc.doReq(req)
	if err != nil {
		if strings.Contains(err.Error(), "Token is expired") &&
			!strings.Contains(err.Error(), "unable to authenticate the refresh token") {
			return hc.loginWithToken()
		}
		return err
	}

View on GitHub (pinned to 8cc6e09de2)

Solutions

  1. Verify the credentials struct passed to loginWithCredentials contains only JSON-encodable fields (strings, numbers); no funcs, channels, or reference cycles.
  2. If you customized the creds type, add json tags and remove unsupported field types.
  3. Confirm you are on an unmodified version of internal/sources/dgraph/dgraph.go; rebuild from upstream sources.
  4. If the error persists, log the wrapped %v error — it names the exact value json.Marshal failed on.

Example fix

// before
type creds struct {
  Callback func() `json:"-"` // unsupported for JSON
  User     string
  Password string
}
// after
type creds struct {
  User     string `json:"user"`
  Password string `json:"password"`
}
Defensive patterns

Strategy: validation

Validate before calling

for _, c := range []interface{}{creds} {
  if _, err := json.Marshal(c); err != nil {
    return fmt.Errorf("credentials not JSON-encodable: %w", err)
  }
}

Try / catch

if err := loginWithCredentials(ctx, user, pass); err != nil {
  if strings.Contains(err.Error(), "failed to marshal credentials") {
    // inspect the creds struct for unsupported field types
  }
}

Prevention

When it happens

Trigger: json.Marshal(creds) returns a non-nil error inside doLogin. With the current creds struct (reset_password/user/password strings) this cannot occur; it would only fire if the credentials type were changed to include unsupported values (channels, funcs, or cyclic data).

Common situations: Developers essentially never hit this at runtime. It can surface after custom forks or refactors that replace the creds struct with types containing unsupported fields (e.g. func or chan members) or introduce cyclic references.

Understand the failure class

Background: json.Marshal / "failed to marshal" errors in Go: why "unsupported type" happens and how to fix it — this error's family across 22 libraries.

Related errors


AI-assisted analysis of googleapis/mcp-toolbox@8cc6e09de2 (2026-09-05). Data as JSON: /api/errors/c00c5e856f1b892c. Report an issue: GitHub.