{"record":{"id":"bef116b05fa629eb","repo":"gofr-dev/gofr","slug":"w-s-bef116","errorCode":null,"errorMessage":"%w: %s","messagePattern":"%w: %s","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"pkg/gofr/datasource/kv-store/nats/nats.go","lineNumber":116,"sourceCode":"\t\tBucket: c.configs.Bucket,\n\t})\n\tif err != nil {\n\t\tc.logger.Errorf(\"error while creating/accessing KV bucket: %v\", err)\n\t\treturn\n\t}\n\n\tc.kv = kv\n\tc.logger.Infof(\"successfully connected to NATS-KV Store at %s:%s \", c.configs.Server, c.configs.Bucket)\n}\n\nfunc (c *Client) Get(ctx context.Context, key string) (string, error) {\n\tspan := c.addTrace(ctx, \"get\", key)\n\tdefer c.sendOperationStats(time.Now(), \"GET\", \"get\", span, key)\n\n\tentry, err := c.kv.Get(key)\n\tif err != nil {\n\t\tif errors.Is(err, nats.ErrKeyNotFound) {\n\t\t\treturn \"\", fmt.Errorf(\"%w: %s\", errKeyNotFound, key)\n\t\t}\n\n\t\treturn \"\", fmt.Errorf(\"failed to get key: %w\", err)\n\t}\n\n\treturn string(entry.Value()), nil\n}\n\nfunc (c *Client) Set(ctx context.Context, key, value string) error {\n\tspan := c.addTrace(ctx, \"set\", key)\n\tdefer c.sendOperationStats(time.Now(), \"SET\", \"set\", span, key, value)\n\n\t_, err := c.kv.Put(key, []byte(value))\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to set key-value pair: %w\", err)\n\t}\n\n\treturn nil","sourceCodeStart":98,"sourceCodeEnd":134,"githubUrl":"https://github.com/gofr-dev/gofr/blob/187eb24962502e91f1fee856230670958b66e89c/pkg/gofr/datasource/kv-store/nats/nats.go#L98-L134","documentation":"NATS KV Get translates nats.ErrKeyNotFound from the underlying bucket into this library's sentinel: fmt.Errorf(\"%w: %s\", errKeyNotFound, key), producing 'key not found: <key>'. The %w wrap preserves errors.Is matching against the library's errKeyNotFound. Other KV errors take a different path ('failed to get key').","triggerScenarios":"c.kv.Get(key) returns nats.ErrKeyNotFound — the key has no entry in the JetStream bucket (never written, deleted, or TTL-expired).","commonSituations":"Expired keys (bucket MaxAge), reading keys written to another bucket, miss-heavy cache lookups, key naming typos.","solutions":["Use errors.Is(err, errKeyNotFound) to branch on miss and provide a default/fetch-from-source path","Verify bucket consistency between producers and consumers","Extend the bucket TTL if legitimate keys expire","Log the key from the message to debug naming mismatches"],"exampleFix":"// before\nv, err := store.Get(ctx, key)\nreturn v, err\n// after\nv, err := store.Get(ctx, key)\nif errors.Is(err, kv.ErrKeyNotFound) { return loadFromDB(key) }\nif err != nil { return err }","handlingStrategy":"fallback","validationCode":"// validate key format and non-emptiness before Get\nif key == \"\" || !keyRe.MatchString(key) { return fmt.Errorf(\"invalid key %q\", key) }","typeGuard":"func IsKeyNotFound(err error) bool { return errors.Is(err, natskv.ErrKeyNotFound) }","tryCatchPattern":"v, err := store.Get(ctx, key)\nif errors.Is(err, natskv.ErrKeyNotFound) {\n    return loadFromSource(key) // miss path\n}\nif err != nil { return fmt.Errorf(\"get %s: %w\", key, err) }","preventionTips":["Treat key-not-found as expected control flow, log at debug level","Standardize key naming in a keys package","Set TTLs deliberately and document them","Keep miss-path latency low (local default or DB fallback)"],"tags":["nats","jetstream","key-not-found","kv-store"],"backgroundTag":"key-not-found","analyzedSha":"187eb24962502e91f1fee856230670958b66e89c","analyzedAt":"2026-09-01T20:34:54.554Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}