{"record":{"id":"ebbfcb8b40b74944","repo":"neondatabase/neon","slug":"no-timelines-found","errorCode":null,"errorMessage":"no timelines found","messagePattern":"no timelines found","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pageserver/pagebench/src/cmd/idle_streams.rs","lineNumber":58,"sourceCode":"\nasync fn main_impl(args: Args) -> anyhow::Result<()> {\n    // Discover a tenant and timeline to use.\n    let mgmt_api_client = Arc::new(pageserver_client::mgmt_api::Client::new(\n        reqwest::Client::new(),\n        args.http_server.clone(),\n        None,\n    ));\n    let timelines: Vec<TenantTimelineId> = crate::util::cli::targets::discover(\n        &mgmt_api_client,\n        crate::util::cli::targets::Spec {\n            limit_to_first_n_targets: Some(1),\n            targets: None,\n        },\n    )\n    .await?;\n    let ttid = timelines\n        .first()\n        .ok_or_else(|| anyhow!(\"no timelines found\"))?;\n\n    // Set up the initial client.\n    let endpoint = Endpoint::from_shared(args.server.clone())?;\n\n    let connect = async || {\n        pageserver_page_api::Client::new(\n            endpoint.connect().await?,\n            ttid.tenant_id,\n            ttid.timeline_id,\n            ShardIndex::unsharded(),\n            None,\n            None,\n        )\n    };\n\n    let mut client = connect().await?;\n    let mut streams = Vec::with_capacity(args.count);\n","sourceCodeStart":40,"sourceCodeEnd":76,"githubUrl":"https://github.com/neondatabase/neon/blob/8f60b04da47ffefe0e52bda2440134b42874eb75/pageserver/pagebench/src/cmd/idle_streams.rs#L40-L76","documentation":"idle_streams picks a victim timeline by calling targets::discover with limit_to_first_n_targets: Some(1). If the pageserver management API returns an empty timeline list, timelines.first() is None and the command fails with 'no timelines found' before opening any stream.","triggerScenarios":"Running idle_streams against a pageserver with zero attached tenants; pointing --mgmt-api-endpoint at the wrong host or at the page_service port so the tenant list comes back empty; all tenants deleted or in a state excluded from listing.","commonSituations":"A fresh dev or staging pageserver before any tenant is created; after tenant migration or deletion; port confusion between the management API and other listeners.","solutions":["Verify the management API endpoint, e.g. curl http://<host>:6400/v1/tenant returns a non-empty list","Create or attach a tenant and timeline and wait until it reports active","Re-run idle_streams once the tenant appears in the list"],"exampleFix":"# before\nidle_streams --mgmt-api-endpoint http://wrong-host:6400 ...\n# after\n# 1) confirm the tenant list is non-empty\ncurl -s http://localhost:6400/v1/tenant | jq length   # must be > 0\n# 2) run the bench against the same endpoint\nidle_streams --mgmt-api-endpoint http://localhost:6400 ...","handlingStrategy":"validation","validationCode":"let timelines = crate::util::cli::targets::discover(\n    &mgmt_api_client,\n    Spec { limit_to_first_n_targets: Some(1), targets: None },\n).await?;\nif timelines.is_empty() {\n    anyhow::bail!(\"no timelines on this pageserver; create or attach a tenant first\");\n}","typeGuard":null,"tryCatchPattern":"let ttid = match timelines.first() {\n    Some(ttid) => *ttid,\n    None => {\n        eprintln!(\"no timelines found: check --mgmt-api-endpoint and tenant state\");\n        return Err(anyhow!(\"no timelines found\"));\n    }\n};","preventionTips":["Smoke-test GET /v1/tenant before running discovery-based benches","Wait for tenant activation (poll until active) after creating tenants","Keep management-API and page_service endpoints in distinct documented variables"],"tags":["pagebench","idle-streams","discovery","management-api","tenants"],"backgroundTag":"empty-resource-list","analyzedSha":"8f60b04da47ffefe0e52bda2440134b42874eb75","analyzedAt":"2026-08-16T23:39:28.135Z","schemaVersion":2},"datasetVersion":"2026-08-17T04:17:16.089Z"}