{"record":{"id":"c60ce64fa114952a","repo":"ipfs/kubo","slug":"no-sources-specified","errorCode":null,"errorMessage":"no sources specified","messagePattern":"no sources specified","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"repo/fsrepo/migrations/migrations.go","lineNumber":202,"sourceCode":"\t\tdefault:\n\t\t\tu, err := url.Parse(src)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"bad gateway address: %w\", err)\n\t\t\t}\n\t\t\tswitch u.Scheme {\n\t\t\tcase \"\":\n\t\t\t\tu.Scheme = \"https\"\n\t\t\tcase \"https\", \"http\":\n\t\t\tdefault:\n\t\t\t\treturn nil, errors.New(\"bad gateway address: url scheme must be http or https\")\n\t\t\t}\n\t\t\tfetchers = append(fetchers, NewHttpFetcher(distPath, u.String(), httpUserAgent, 0))\n\t\t}\n\t}\n\n\tswitch len(fetchers) {\n\tcase 0:\n\t\treturn nil, errors.New(\"no sources specified\")\n\tcase 1:\n\t\treturn fetchers[0], nil\n\t}\n\n\t// Wrap fetchers in a MultiFetcher to try them in order\n\treturn NewMultiFetcher(fetchers...), nil\n}\n\nfunc migrationName(from, to int) string {\n\treturn fmt.Sprintf(\"fs-repo-%d-to-%d\", from, to)\n}\n\n// findMigrations returns a list of migrations, ordered from first to last\n// migration to apply, and a map of locations of migration binaries of any\n// migrations that were found.\n//\n// Deprecated: This function is used by legacy migration downloads and will be removed\n// in a future version.","sourceCodeStart":184,"sourceCodeEnd":220,"githubUrl":"https://github.com/ipfs/kubo/blob/329838acdfafae224582930457efe80aa217afc0/repo/fsrepo/migrations/migrations.go#L184-L220","documentation":"GetMigrationFetcher builds a list of fetchers (HTTP and/or IPFS) from the configured DownloadSources. If the sources list is empty after processing, no fetcher can be constructed, so it returns this error instead of a nil-capable Fetcher. It is a guard against running migrations with no place to download migration binaries from.","triggerScenarios":"Calling GetMigrationFetcher with an empty DownloadSources slice, or with sources that all fail to produce a fetcher (e.g. all entries invalid/unsupported schemes), so the fetchers slice ends up empty.","commonSituations":"Fresh ipfs repos or CI environments where the migrations config file is missing or has no DownloadSources set; users who cleared IPFS_DIST_PATH or the migration config's download sources; tests constructing a fetcher with nil/empty source lists.","solutions":["Set DownloadSources in the migrations config file (e.g. IPFS_PATH/migrations config) to a valid distribution URL","Export IPFS_DIST_PATH to a mirror serving ipfs-update distributions","Check ReadMigrationConfig output: the second return of GetMigrationFetcher's first argument comes from the config; ensure it is populated","If running fully offline, obtain migration binaries another way (PATH lookup) instead of calling GetMigrationFetcher"],"exampleFix":"// before\nfetcher, err := GetMigrationFetcher(nil, GetDistPathEnv(CurrentIpfsDist), nil) // sources nil\n// after\nsources := cfg.DownloadSources\nif len(sources) == 0 {\n    sources = []string{\"https://dist.ipfs.tech\"}\n}\nfetcher, err := GetMigrationFetcher(sources, GetDistPathEnv(CurrentIpfsDist), nil)","handlingStrategy":"validation","validationCode":"sources := cfg.DownloadSources\nif len(sources) == 0 {\n    sources = []string{\"https://dist.ipfs.tech\"}\n}\nfetcher, err := migration.GetMigrationFetcher(sources, migration.GetDistPathEnv(migration.CurrentIpfsDist), nil)","typeGuard":null,"tryCatchPattern":"if err != nil {\n    if err.Error() == \"no sources specified\" {\n        return fmt.Errorf(\"configure DownloadSources or set IPFS_DIST_PATH: %w\", err)\n    }\n    return err\n}","preventionTips":["Always pass a non-empty, non-nil DownloadSources slice","Default to https://dist.ipfs.tech when config has no sources","Validate config parsing before constructing fetchers","Document required config for offline/mirror setups"],"tags":["migrations","configuration","network-download"],"backgroundTag":"migration-download-sources-missing","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"}