{"record":{"id":"71893a68e71b1dbc","repo":"opendatalab/MinerU","slug":"the-provided-path-starts-with-this-does-not-c","errorCode":null,"errorMessage":"The provided path starts with '/'. This does not conform to a valid S3 path format.","messagePattern":"The provided path starts with '/'\\. This does not conform to a valid S3 path format\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"mineru/data/utils/path_utils.py","lineNumber":21,"sourceCode":"\ndef remove_non_official_s3_args(s3path):\n    \"\"\"\n    example: s3://abc/xxxx.json?bytes=0,81350 ==> s3://abc/xxxx.json\n    \"\"\"\n    arr = s3path.split(\"?\")\n    return arr[0]\n\ndef parse_s3path(s3path: str):\n    # from s3pathlib import S3Path\n    # p = S3Path(remove_non_official_s3_args(s3path))\n    # return p.bucket, p.key\n    s3path = remove_non_official_s3_args(s3path).strip()\n    if s3path.startswith(('s3://', 's3a://')):\n        prefix, path = s3path.split('://', 1)\n        bucket_name, key = path.split('/', 1)\n        return bucket_name, key\n    elif s3path.startswith('/'):\n        raise ValueError(\"The provided path starts with '/'. This does not conform to a valid S3 path format.\")\n    else:\n        raise ValueError(\"Invalid S3 path format. Expected 's3://bucket-name/key' or 's3a://bucket-name/key'.\")\n\n\ndef parse_s3_range_params(s3path: str):\n    \"\"\"\n    example: s3://abc/xxxx.json?bytes=0,81350 ==> [0, 81350]\n    \"\"\"\n    arr = s3path.split(\"?bytes=\")\n    if len(arr) == 1:\n        return None\n    return arr[1].split(\",\")\n","sourceCodeStart":3,"sourceCodeEnd":34,"githubUrl":"https://github.com/opendatalab/MinerU/blob/4fe4bde114a23ee5dd637eae99b767f4669bf58c/mineru/data/utils/path_utils.py#L3-L34","documentation":"ValueError from parse_s3path() when the (query-stripped, trimmed) path begins with '/'. The function only accepts 's3://bucket/key' or 's3a://bucket/key'; a leading slash means there is no scheme and no bucket segment, so the path cannot be decomposed into (bucket, key).","triggerScenarios":"parse_s3path('/bucket/key.pdf') or parse_s3path('/data/file.pdf'). Called indirectly by MultiBucketS3DataReader.read_at()/write paths when an absolute filesystem-style path is passed instead of an s3:// URI.","commonSituations":"Mixing local path handling with S3 paths — e.g. os.path.join output, mount paths like '/mnt/s3/bucket', or Path('/bucket/key').as_uri()-style leftovers; refactoring a local-pipeline to S3 without converting path constants.","solutions":["Pass a proper S3 URI: 's3://bucket/key' (or 's3a://bucket/key').","If you have bucket and key separately, build the URI: f's3://{bucket}/{key}'.","If the path is a local file, use a local reader/writer instead of the S3 one.","Strip a leading '/'mount prefix before composing the s3:// URI."],"exampleFix":"# before\nbucket, key = parse_s3path('/my-bucket/doc.pdf')  # ValueError\n\n# after\nbucket, key = parse_s3path('s3://my-bucket/doc.pdf')","handlingStrategy":"validation","validationCode":"def to_s3_uri(path: str) -> str:\n    p = path.strip()\n    if p.startswith(('s3://', 's3a://')):\n        return p\n    if p.startswith('/'):\n        return 's3:/' + p  # '/bucket/key' -> 's3://bucket/key'\n    raise ValueError(f'cannot convert {path!r} to an s3:// URI')\n\nbucket, key = parse_s3path(to_s3_uri(raw_path))","typeGuard":"def looks_like_s3_path(path: str) -> bool:\n    p = path.strip()\n    return p.startswith('s3://') or p.startswith('s3a://')","tryCatchPattern":"try:\n    bucket, key = parse_s3path(path)\nexcept ValueError as e:\n    raise ValueError(f'expected s3://bucket/key, got {path!r}') from e","preventionTips":["Normalize every external path to a full s3:// URI at the system boundary.","Never feed os.path/Path-derived absolute paths into S3 readers.","Add a path-scheme routing layer: local -> local reader, s3:// -> S3 reader."],"tags":["s3","path","validation"],"backgroundTag":null,"analyzedSha":"4fe4bde114a23ee5dd637eae99b767f4669bf58c","analyzedAt":"2026-08-14T21:29:18.456Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}