larksuite/cli · error

file provider JSON parse error: %w

Error message

file provider JSON parse error: %w

What it means

In json mode the secret file must contain valid JSON so a JSON Pointer (ref.ID) can navigate it. json.Unmarshal failed, so the file is malformed JSON (or, commonly, a bare secret string without JSON braces). The parse error is wrapped for diagnosis.

Source

Thrown at internal/binding/secret_resolve_file.go:87

	if mode == "" {
		mode = "json" // default mode per OpenClaw
	}

	switch mode {
	case "singleValue":
		// OpenClaw requires ref.id == SINGLE_VALUE_FILE_REF_ID for singleValue mode
		if ref.ID != SingleValueFileRefID {
			return "", fmt.Errorf("singleValue file provider expects ref id %q, got %q",
				SingleValueFileRefID, ref.ID)
		}
		// Entire file content is the secret; trim trailing newline
		return strings.TrimRight(content, "\r\n"), nil

	case "json":
		// Parse as JSON, then navigate via JSON Pointer (ref.ID)
		var parsed interface{}
		if err := json.Unmarshal(data, &parsed); err != nil {
			return "", fmt.Errorf("file provider JSON parse error: %w", err)
		}

		value, err := ReadJSONPointer(parsed, ref.ID)
		if err != nil {
			return "", fmt.Errorf("file provider JSON Pointer %q: %w", ref.ID, err)
		}

		// Value must be a string
		strValue, ok := value.(string)
		if !ok {
			return "", fmt.Errorf("file provider JSON Pointer %q resolved to non-string value", ref.ID)
		}
		return strValue, nil

	default:
		return "", fmt.Errorf("unsupported file provider mode %q", mode)
	}
}

View on GitHub (pinned to 7fd6ef3c07)

Solutions

  1. Validate the file: `jq . <path>` — fix syntax errors (trailing commas, comments, truncation).
  2. If the file holds one bare secret, either wrap it in JSON (e.g. {"value":"..."} with id "/value") or set Mode to "singleValue".
  3. Ensure the writer of the file serializes atomically (write temp file + rename) to avoid truncated reads.

Example fix

// before (file content, json mode)
s3cret-api-key
// after
{"api_key": "s3cret-api-key"}
// with ref id "/api_key"
Defensive patterns

Strategy: validation

Validate before calling

raw, err := os.ReadFile(os.ExpandEnv(pc.Path))
if err == nil {
    var probe any
    if jerr := json.Unmarshal(raw, &probe); jerr != nil {
        return fmt.Errorf("secret file %s is not valid JSON: %v", pc.Path, jerr)
    }
}

Type guard

func isJSONObject(raw []byte) bool { var v any; return json.Unmarshal(raw, &v) == nil }

Try / catch

secret, err := resolveSecretRef(ctx, ref)
if err != nil {
    if strings.Contains(err.Error(), "JSON parse error") {
        // jq . <path> to locate the syntax problem, or switch mode to singleValue
    }
    return err
}

Prevention

When it happens

Trigger: Calling resolveSecretRef with a {source:"file"} SecretRef in default ("json") mode where the file at Path is not parseable JSON — truncated file, trailing garbage, or a plain-text secret written without JSON encoding.

Common situations: A single-value secret was pasted raw into the file while the provider stayed in json mode; the file got truncated during a partial write or download; encoding issues (BOM) or comments added to the JSON.

Understand the failure class

Related errors


AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04). Data as JSON: /api/errors/fe383d4010b27f2d. Report an issue: GitHub.