{"record":{"id":"000043c4e283890f","repo":"larksuite/cli","slug":"singlevalue-file-provider-expects-ref-id-q-got","errorCode":null,"errorMessage":"singleValue file provider expects ref id %q, got %q","messagePattern":"singleValue file provider expects ref id %q, got %q","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/binding/secret_resolve_file.go","lineNumber":77,"sourceCode":"\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"failed to read secret file %s: %w\", securePath, err)\n\t}\n\n\tif len(data) > maxBytes {\n\t\treturn \"\", fmt.Errorf(\"file provider exceeded maxBytes (%d)\", maxBytes)\n\t}\n\n\tcontent := string(data)\n\tmode := pc.Mode\n\tif mode == \"\" {\n\t\tmode = \"json\" // default mode per OpenClaw\n\t}\n\n\tswitch mode {\n\tcase \"singleValue\":\n\t\t// OpenClaw requires ref.id == SINGLE_VALUE_FILE_REF_ID for singleValue mode\n\t\tif ref.ID != SingleValueFileRefID {\n\t\t\treturn \"\", fmt.Errorf(\"singleValue file provider expects ref id %q, got %q\",\n\t\t\t\tSingleValueFileRefID, ref.ID)\n\t\t}\n\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","sourceCodeStart":59,"sourceCodeEnd":95,"githubUrl":"https://github.com/larksuite/cli/blob/7fd6ef3c07182257ce776cdc5a614e122d5bd4b3/internal/binding/secret_resolve_file.go#L59-L95","documentation":"In singleValue mode the entire file content is the secret, so OpenClaw semantics require the SecretRef id to equal the sentinel SingleValueFileRefID. A different id means the config is inconsistent: the provider would otherwise silently ignore which id the caller asked for.","triggerScenarios":"Calling resolveSecretRef with a {source:\"file\"} SecretRef whose ProviderConfig.Mode is \"singleValue\" but whose ref.ID is not SingleValueFileRefID (e.g. a leftover JSON-pointer-style id like \"/api_key\" from a json-mode config).","commonSituations":"Switching a provider from json to singleValue mode without updating the ref id; copying a ref from a json-mode provider; hand-writing the ref with an intuitive custom id.","solutions":["Change the SecretRef id to SingleValueFileRefID when using singleValue mode.","Or, if you need per-key lookup, switch ProviderConfig.Mode to \"json\" and keep your pointer id.","Audit provider mode and ref id pairs in the binding config so they stay consistent."],"exampleFix":"// before\n{\"source\":\"file\",\"id\":\"/api_key\"}  // mode: singleValue\n// after\n{\"source\":\"file\",\"id\":\"SINGLE_VALUE_FILE_REF_ID\"}  // use the exported sentinel constant's value\n// or set provider mode to \"json\" and keep the pointer id","handlingStrategy":"validation","validationCode":"if pc.Mode == \"singleValue\" && ref.ID != SingleValueFileRefID {\n    return fmt.Errorf(\"config error: singleValue mode requires ref id %q\", SingleValueFileRefID)\n}","typeGuard":null,"tryCatchPattern":"secret, err := resolveSecretRef(ctx, ref)\nif err != nil {\n    if strings.Contains(err.Error(), \"expects ref id\") {\n        // fix the ref id or switch the provider mode to json\n    }\n    return err\n}","preventionTips":["When switching a provider between json and singleValue, update every ref id in the same change.","Centralize ref construction so the sentinel id is used for singleValue providers.","Add a config lint that pairs mode with the expected ref id."],"tags":["secrets","file-provider","config","validation"],"backgroundTag":"configuration-mismatch","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"}