{"record":{"id":"84e001e3600ee732","repo":"ipfs/kubo","slug":"pin-s","errorCode":null,"errorMessage":"pin: %s","messagePattern":"pin: %s","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/coreapi/pin.go","lineNumber":30,"sourceCode":"\tpin \"github.com/ipfs/boxo/pinning/pinner\"\n\t\"github.com/ipfs/go-cid\"\n\tcoreiface \"github.com/ipfs/kubo/core/coreiface\"\n\tcaopts \"github.com/ipfs/kubo/core/coreiface/options\"\n\t\"go.opentelemetry.io/otel/attribute\"\n\t\"go.opentelemetry.io/otel/trace\"\n\n\t\"github.com/ipfs/kubo/tracing\"\n)\n\ntype PinAPI CoreAPI\n\nfunc (api *PinAPI) Add(ctx context.Context, p path.Path, opts ...caopts.PinAddOption) error {\n\tctx, span := tracing.Span(ctx, \"CoreAPI.PinAPI\", \"Add\", trace.WithAttributes(attribute.String(\"path\", p.String())))\n\tdefer span.End()\n\n\tdagNode, err := api.core().ResolveNode(ctx, p)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"pin: %s\", err)\n\t}\n\n\tsettings, err := caopts.PinAddOptions(opts...)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tspan.SetAttributes(attribute.Bool(\"recursive\", settings.Recursive))\n\n\tdefer api.blockstore.PinLock(ctx).Unlock(ctx)\n\n\terr = api.pinning.Pin(ctx, dagNode, settings.Recursive, settings.Name)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"pin: %s\", err)\n\t}\n\n\treturn api.pinning.Flush(ctx)\n}","sourceCodeStart":12,"sourceCodeEnd":48,"githubUrl":"https://github.com/ipfs/kubo/blob/329838acdfafae224582930457efe80aa217afc0/core/coreapi/pin.go#L12-L48","documentation":"PinAPI.Add first resolves the given path to a node; any resolution failure (bad path, unsupported namespace, missing block) is wrapped with a 'pin: ' prefix. The error is a wrapper — the underlying cause (from ResolveNode) is embedded after the prefix.","triggerScenarios":"Calling Pin().Add with a path that cannot be resolved: nonexistent CID, /ipns/ path, malformed path, or a path whose blocks are not present locally and cannot be fetched.","commonSituations":"Pinning a CID that exists on the network but the node is offline; pinning an IPNS name without the pin API supporting that namespace; typo'd CID.","solutions":["Read the wrapped cause after 'pin: ' to identify the real failure","Verify the CID exists locally: 'ipfs block stat' or 'ipfs cat'","Resolve IPNS/namespace issues before pinning (pin the /ipfs/ path)","Ensure the daemon has connectivity to fetch the content before pinning"],"exampleFix":"// before\nerr := api.Pin().Add(ctx, path.New(\"/ipns/example.com\")) // pin: unsupported path namespace\n// after\nnd, err := api.ResolveNode(ctx, path.New(\"/ipns/example.com\"))\nif err == nil {\n    err = api.Pin().Add(ctx, path.FromCid(nd.Cid()))\n}","handlingStrategy":"try-catch","validationCode":"// ensure path is /ipfs/-namespaced and the CID is present locally\n_, err := api.Block().Stat(ctx, p)\nif err != nil {\n    // fetch/resolve before pinning\n}","typeGuard":"func isIPFSPath(p path.Path) bool { return p.Namespace() == path.IPFSNamespace }","tryCatchPattern":"err := api.Pin().Add(ctx, p, opts...)\nif err != nil {\n    var cause error\n    if strings.HasPrefix(err.Error(), \"pin: \") {\n        // unwrap and inspect the resolution failure after \"pin: \"\n    }\n    return fmt.Errorf(\"pin add failed: %w\", err)\n}","preventionTips":["Resolve paths to /ipfs/ CIDs before pinning","Verify content availability (block stat / cat) before pin add","Use errors.Is/As on the wrapped cause when possible"],"tags":["pin","path-resolution","error-wrapping"],"backgroundTag":"pin-path-resolution-failed","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"}