{"record":{"id":"f11d458b8d15da77","repo":"ipfs/kubo","slug":"r-string","errorCode":null,"errorMessage":"r.String()","messagePattern":"r\\.String\\(\\)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"blocks/blockstoreutil/remove.go","lineNumber":91,"sourceCode":"// FilterPinned takes a slice of Cids and returns it with the pinned Cids\n// removed. If a Cid is pinned, it will place RemovedBlock objects in the given\n// out channel, with an error which indicates that the Cid is pinned.\n// This function is used in RmBlocks to filter out any blocks which are not\n// to be removed (because they are pinned).\nfunc FilterPinned(ctx context.Context, pins pin.Pinner, out chan<- any, cids []cid.Cid) []cid.Cid {\n\tstillOkay := make([]cid.Cid, 0, len(cids))\n\tres, err := pins.CheckIfPinned(ctx, cids...)\n\tif err != nil {\n\t\tout <- &RemovedBlock{Error: fmt.Errorf(\"pin check failed: %w\", err)}\n\t\treturn nil\n\t}\n\tfor _, r := range res {\n\t\tif !r.Pinned() {\n\t\t\tstillOkay = append(stillOkay, r.Key)\n\t\t} else {\n\t\t\tout <- &RemovedBlock{\n\t\t\t\tHash:  r.Key.String(),\n\t\t\t\tError: errors.New(r.String()),\n\t\t\t}\n\t\t}\n\t}\n\treturn stillOkay\n}\n","sourceCodeStart":73,"sourceCodeEnd":97,"githubUrl":"https://github.com/ipfs/kubo/blob/329838acdfafae224582930457efe80aa217afc0/blocks/blockstoreutil/remove.go#L73-L97","documentation":"When FilterPinned finds a CID that IS pinned, it does not return an error; it emits a RemovedBlock whose Error field contains the text of pin.Info r.String() — i.e. a human-readable reason such as 'recursive', 'direct', or 'through <parent>'. This is the library's way of telling the caller per-CID why a block was skipped from removal, not a real failure.","triggerScenarios":"Calling RmBlocks (or 'ipfs block rm') with CIDs that are pinned directly, recursively, or indirectly through a parent pin; the pinned info string becomes the per-block 'error'.","commonSituations":"Scripts doing 'ipfs block rm <cid>' on blocks still pinned by 'ipfs pin add'; batch GC scripts that did not run 'ipfs pin rm' first; confusion when per-block errors look like failures but mean 'skipped, pinned'.","solutions":["Treat this RemovedBlock.Error as informational: the block was skipped because it is pinned","Unpin first with `ipfs pin rm <cid>`, then retry the block removal","Filter pins beforehand by calling pins.CheckIfPinned yourself and excluding pinned CIDs","Parse the info string or, better, consume CheckIfPinned results directly instead of the string"],"exampleFix":"// before\nout <- &RemovedBlock{Hash: r.Key.String(), Error: errors.New(r.String())}\n// after: caller-side guard\nres, _ := pins.CheckIfPinned(ctx, cids...)\nvar removable []cid.Cid\nfor _, r := range res { if !r.Pinned() { removable = append(removable, r.Key) } }","handlingStrategy":"type-guard","validationCode":"res, err := pins.CheckIfPinned(ctx, cids...)\nvar removable []cid.Cid\nfor _, r := range res {\n    if !r.Pinned() { removable = append(removable, r.Key) }\n}","typeGuard":"func isPinnedNotice(err error) bool {\n    // pinned-skip 'errors' carry the pin info string, not a failure\n    return err != nil && (strings.Contains(err.Error(), \"recursive\") ||\n        strings.Contains(err.Error(), \"direct\") ||\n        strings.Contains(err.Error(), \"through \"))\n}","tryCatchPattern":"for rb := range out {\n    b, ok := rb.(*blockstoreutil.RemovedBlock)\n    if ok && b.Error != nil && isPinnedNotice(b.Error) {\n        log.Printf(\"skipped %s (pinned): %s\", b.Hash, b.Error)\n        continue // informational, not a failure\n    }\n}","preventionTips":["Unpin before block rm: `ipfs pin rm <cid>`","Check pins with `ipfs pin ls <cid>` before removal","Treat RemovedBlock.Error on pinned blocks as status, not failure"],"tags":["go","ipfs","pins","blocks"],"backgroundTag":"block-pinned-skipped","analyzedSha":"329838acdfafae224582930457efe80aa217afc0","analyzedAt":"2026-09-03T18:30:52.135Z","contentChangedAt":"2026-09-03T18:30:52.135Z","schemaVersion":2},"datasetVersion":"2026-09-11T00:17:11.886Z"}