{"record":{"id":"ae87fcab1f7f88f8","repo":"risingwavelabs/risingwave","slug":"s3-url-location-should-have-a-at-the-start-o","errorCode":null,"errorMessage":"s3 url {location} should have a '/' at the start of path.","messagePattern":"s3 url (.+?) should have a '/' at the start of path\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/connector/src/aws_utils.rs","lineNumber":117,"sourceCode":"            .build()\n    } else {\n        s3_config::Config::new(sdk_config)\n    };\n    s3_client::Client::from_conf(s3_config_obj)\n}\n\n// TODO(Tao): Probably we should never allow to use S3 URI.\npub async fn load_file_descriptor_from_s3(\n    location: &Url,\n    config: &AwsAuthProps,\n) -> ConnectorResult<Vec<u8>> {\n    let bucket = location\n        .domain()\n        .with_context(|| format!(\"illegal file path {}\", location))?;\n    let key = location\n        .path()\n        .strip_prefix('/')\n        .ok_or_else(|| anyhow!(\"s3 url {location} should have a '/' at the start of path.\"))?;\n    let sdk_config = config.build_config().await?;\n    let s3_client = s3_client(&sdk_config, Some(default_conn_config()));\n    let response = s3_client\n        .get_object()\n        .bucket(bucket.to_owned())\n        .key(key)\n        .send()\n        .await\n        .with_context(|| format!(\"failed to get file from s3 at `{}`\", location))?;\n\n    let body = response\n        .body\n        .collect()\n        .await\n        .with_context(|| format!(\"failed to read file from s3 at `{}`\", location))?;\n    Ok(body.into_bytes().to_vec())\n}\n","sourceCodeStart":99,"sourceCodeEnd":135,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/connector/src/aws_utils.rs#L99-L135","documentation":"Raised by `load_file_descriptor_from_s3` in aws_utils.rs when an S3 location URL's path component does not start with '/'. The code strips the leading '/' from `url.path()` to derive the object key; `strip_prefix('/')` returning None means the URL was malformed (no root path), so the S3 GET would use an invalid key.","triggerScenarios":"Passing an S3 location like `s3://bucket` (no trailing slash/path) or a URL whose path lacks the leading slash into functions that call `load_file_descriptor_from_s3` such as `bytes_from_url` or `get_auth_json_from_path`.","commonSituations":"Typing `s3://mybucket` instead of `s3://mybucket/key` in a source/secret file path config; building the URL programmatically and forgetting the path segment.","solutions":["Include the object key with a leading slash in the location, e.g. `s3://bucket/path/to/file.json`.","If listing bucket contents is intended, use `s3://bucket/` with the trailing slash.","Validate the URL shape before passing it to S3-loading APIs."],"exampleFix":"// before\nlet url = \"s3://my-bucket\";\n// after\nlet url = \"s3://my-bucket/credentials.json\";","handlingStrategy":"validation","validationCode":"function validateS3Url(u) {\n  const url = new URL(u);\n  if (url.protocol !== 's3:') throw new Error('not an s3 url');\n  if (!url.pathname.startsWith('/') || url.pathname.length < 2) {\n    throw new Error(`s3 url ${u} must include a key path like s3://bucket/key`);\n  }\n}\nvalidateS3Url('s3://my-bucket/creds.json');","typeGuard":null,"tryCatchPattern":"try { const bytes = await bytesFromUrl(loc); } catch (e) { if (String(e).includes(\"should have a '/' at the start of path\")) throw new Error(`Malformed S3 location '${loc}': include the object key, e.g. s3://bucket/key`); throw e; }","preventionTips":["Always store full s3://bucket/key URLs, never bare bucket names.","Validate location strings with a URL parse before saving configs.","Keep a trailing key in templated configs; require the field non-empty."],"tags":["s3","url","aws","path"],"backgroundTag":"invalid-url-format","analyzedSha":"6469eb736d691e8e9b8a419a57edd6429ca77417","analyzedAt":"2026-09-11T21:06:21.487Z","contentChangedAt":"2026-09-11T21:06:21.487Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}