{"record":{"id":"9806623164c39aba","repo":"jdx/mise","slug":"rel-is-not-a-directory-of-the-repository","errorCode":null,"errorMessage":"{rel} is not a directory of the repository","messagePattern":"(.+?) is not a directory of the repository","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/packslip.rs","lineNumber":483,"sourceCode":"    commit: &str,\n    rel: &str,\n    dest: &Path,\n    pr: &dyn SingleReport,\n) -> Result<()> {\n    let url = format!(\n        \"https://api.github.com/repos/{repo}/contents/{}?ref={commit}\",\n        url_path(rel)\n    );\n    // The client asks for the raw media type on every contents URL, which\n    // is right for a file body and wrong for a directory listing.\n    let mut headers = github::get_headers(&url)?;\n    headers.insert(\n        reqwest::header::ACCEPT,\n        HeaderValue::from_static(\"application/vnd.github+json\"),\n    );\n    let listing: serde_json::Value = HTTP_FETCH.json_with_headers(&url, &headers).await?;\n    let Some(entries) = listing.as_array() else {\n        bail!(\"{rel} is not a directory of the repository\");\n    };\n    file::create_dir_all(dest)?;\n    for entry in entries {\n        let Some(name) = entry[\"name\"].as_str() else {\n            continue;\n        };\n        if !file::is_plain_file_name(name) {\n            continue;\n        }\n        match entry[\"type\"].as_str() {\n            Some(\"dir\") => {\n                Box::pin(fetch_repo_dir(\n                    repo,\n                    commit,\n                    &format!(\"{rel}/{name}\"),\n                    &dest.join(name),\n                    pr,\n                ))","sourceCodeStart":465,"sourceCodeEnd":501,"githubUrl":"https://github.com/jdx/mise/blob/afd2eddd3a50c16190efc1c7e94404b48f72af57/src/packslip.rs#L465-L501","documentation":"packslip's fetch_repo_dir downloads a directory listing of a repo path via the GitHub API. It expects the JSON response to be an array of directory entries; if the API returns anything else (e.g. an object describing a single file, or an error payload), it means the requested path is not a directory in that repository at that ref. The bail conveys that the path must point at a directory to fetch its files.","triggerScenarios":"Calling fetch_repo_dir (directly or via fetch_files) with a `rel` path that is a single file, a nonexistent path, or a repo/ref that returns a non-array listing from the GitHub contents endpoint.","commonSituations":"A packslip manifest points at a file instead of a directory; the file was renamed or deleted upstream so the path 404s and the API returns an error object instead of an array; the ref (tag/commit) no longer contains the directory.","solutions":["Verify the `rel` path in the manifest is a directory that exists in the repo at the requested ref (check on GitHub).","Confirm the ref/commit/tag being fetched still contains that directory; update to a ref where it exists.","If the target is a single file, use the file-fetch path instead of a directory fetch.","Check for GitHub API error responses (rate limiting, auth) that can replace the array with an error object; set a token if rate limited."],"exampleFix":"// before: manifest points at a single file as a dir\nfetch_dir = \"src/packslip.rs\"\n\n// after\nfetch_dir = \"src\"","handlingStrategy":"validation","validationCode":"async fn is_repo_dir(rel: &str, ref_: &str) -> bool {\n    // GitHub contents API returns an array for directories, an object for files\n    let listing = list_repo_dir(rel, ref_).await.ok();\n    matches!(listing, Some(serde_json::Value::Array(_)))\n}","typeGuard":"let Some(entries) = listing.as_array() else { return Err(...); };","tryCatchPattern":"match fetch_repo_dir(rel, ref).await {\n    Err(e) if e.to_string().contains(\"is not a directory\") => eprintln!(\"{rel} is not a dir at {ref}; check the manifest path\"),\n    Ok(entries) => use_entries(entries),\n    Err(e) => return Err(e),\n}","preventionTips":["Point directory fetches only at directories; list file paths separately.","Pin the ref and verify the path exists at that ref before adding it to a manifest.","Watch for GitHub API error payloads (auth/rate limit) masquerading as 'not a directory'."],"tags":["github","http","packslip","directory"],"backgroundTag":"path-is-not-a-directory","analyzedSha":"afd2eddd3a50c16190efc1c7e94404b48f72af57","analyzedAt":"2026-09-09T01:38:25.179Z","contentChangedAt":"2026-09-09T01:38:25.179Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}