{"record":{"id":"c87a7951b2bf69b4","repo":"larksuite/cli","slug":"file-provider-json-pointer-q-resolved-to-non-stri","errorCode":null,"errorMessage":"file provider JSON Pointer %q resolved to non-string value","messagePattern":"file provider JSON Pointer %q resolved to non-string value","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/binding/secret_resolve_file.go","lineNumber":98,"sourceCode":"\t\t// Entire file content is the secret; trim trailing newline\n\t\treturn strings.TrimRight(content, \"\\r\\n\"), nil\n\n\tcase \"json\":\n\t\t// Parse as JSON, then navigate via JSON Pointer (ref.ID)\n\t\tvar parsed interface{}\n\t\tif err := json.Unmarshal(data, &parsed); err != nil {\n\t\t\treturn \"\", fmt.Errorf(\"file provider JSON parse error: %w\", err)\n\t\t}\n\n\t\tvalue, err := ReadJSONPointer(parsed, ref.ID)\n\t\tif err != nil {\n\t\t\treturn \"\", fmt.Errorf(\"file provider JSON Pointer %q: %w\", ref.ID, err)\n\t\t}\n\n\t\t// Value must be a string\n\t\tstrValue, ok := value.(string)\n\t\tif !ok {\n\t\t\treturn \"\", fmt.Errorf(\"file provider JSON Pointer %q resolved to non-string value\", ref.ID)\n\t\t}\n\t\treturn strValue, nil\n\n\tdefault:\n\t\treturn \"\", fmt.Errorf(\"unsupported file provider mode %q\", mode)\n\t}\n}\n","sourceCodeStart":80,"sourceCodeEnd":106,"githubUrl":"https://github.com/larksuite/cli/blob/7fd6ef3c07182257ce776cdc5a614e122d5bd4b3/internal/binding/secret_resolve_file.go#L80-L106","documentation":"The JSON Pointer resolved successfully, but the value it found is not a JSON string (e.g. a number, boolean, object, array, or null). The provider only accepts string secrets, so a non-string at the pointer location is rejected rather than coerced.","triggerScenarios":"Calling resolveSecretRef with a {source:\"file\"} SecretRef in json mode where ref.ID points at a numeric, boolean, null, or nested value — e.g. id \"/port\" resolving to 8080, or \"/credentials\" resolving to an object.","commonSituations":"Pointing at numeric fields (ports, TTLs, key versions) or booleans; YAML-authored secrets that got converted to native types; credentials blobs stored as nested objects with the pointer aimed one level too high.","solutions":["Point ref.ID at the specific string field, e.g. \"/credentials/password\" instead of \"/credentials\".","Quote the value in the secret file so it is a JSON string: \"8080\" instead of 8080.","Store numbers/booleans outside the secret provider if they are not actual secrets."],"exampleFix":"// before: file is {\"port\": 8080}, ref id \"/port\"\n// after\n{\"port\": \"8080\"}\n// or target the string field: {\"db\":{\"password\":\"s3cret\"}} with id \"/db/password\"","handlingStrategy":"type-guard","validationCode":"var doc map[string]any\nraw, _ := os.ReadFile(os.ExpandEnv(pc.Path))\nif json.Unmarshal(raw, &doc) == nil {\n    if v, err := ReadJSONPointer(doc, ref.ID); err == nil {\n        if _, ok := v.(string); !ok {\n            return fmt.Errorf(\"ref %q must point at a JSON string, got %T\", ref.ID, v)\n        }\n    }\n}","typeGuard":"func isJSONString(v any) bool { _, ok := v.(string); return ok }","tryCatchPattern":"secret, err := resolveSecretRef(ctx, ref)\nif err != nil {\n    if strings.Contains(err.Error(), \"non-string value\") {\n        // deepen the pointer or quote the value in the file\n    }\n    return err\n}","preventionTips":["Point ids at leaf string fields, never at objects, arrays, numbers, or null.","Quote numeric-looking secrets (ports, versions) in the JSON file.","After editing the secret file, run `jq -r '<pointer>' <file>` to confirm a bare string comes out."],"tags":["secrets","file-provider","json-pointer","type-mismatch"],"backgroundTag":"secret-provider-non-string-value","analyzedSha":"7fd6ef3c07182257ce776cdc5a614e122d5bd4b3","analyzedAt":"2026-09-04T21:17:44.649Z","contentChangedAt":"2026-09-04T21:17:44.649Z","schemaVersion":2},"datasetVersion":"2026-09-12T02:17:10.037Z"}