can1357/oh-my-pi · error · ArchiveError
Unsupported Rock Ridge relocated directory (${susp.relocatio
Error message
Unsupported Rock Ridge relocated directory (${susp.relocation}) What it means
Rock Ridge allows directories to be 'relocated' (deep-directory hacks via CL/RE and PL/NM SUSP entries) so ISO 9660's 8-level nesting limit can be bypassed. This reader does not follow relocated directories: when parseSusp reports a relocation target for a directory record during full traversal, it throws instead of silently misrepresenting the tree.
Source
Thrown at packages/utils/src/ar/iso.ts:521
while (work.length > 0) {
const directory = work.pop()!;
if (directory.depth > MAX_DIRECTORY_DEPTH) {
throw invalidIso(`directory hierarchy exceeds ${MAX_DIRECTORY_DEPTH} levels`);
}
const records = await readDirectoryRecords(source, directory.record, blockSize, budget, limits);
if (
directory.depth === 0 &&
records.length > 0 &&
records[0]!.identifier.byteLength === 1 &&
records[0]!.identifier[0] === 0
) {
suspSkip = findSuspSkip(records[0]!);
}
for (const record of records) {
if (record.identifier.byteLength === 1 && (record.identifier[0] === 0 || record.identifier[0] === 1)) continue;
const susp = await parseSusp(record, suspSkip, source, blockSize, budget, limits);
if (susp.relocation) {
throw new ArchiveError(`Unsupported Rock Ridge relocated directory (${susp.relocation})`);
}
const rawName = susp.name ?? decodeIdentifier(record.identifier, false);
assertArchivePathBytes(Buffer.byteLength(rawName, "utf-8"), "member name", limits.maxPathBytes);
const rawPath = directory.parentPath ? `${directory.parentPath}/${rawName}` : rawName;
const normalizedPath = normalizeArchiveEntryPath(rawPath);
if (!normalizedPath) continue;
assertArchivePathBytes(Buffer.byteLength(normalizedPath, "utf-8"), "member path", limits.maxPathBytes);
if (susp.symlink !== undefined) {
assertArchivePathBytes(Buffer.byteLength(susp.symlink, "utf-8"), "link target", limits.maxPathBytes);
const targetPath = path.posix.isAbsolute(susp.symlink)
? undefined
: normalizeArchiveLookupPath(path.posix.join(path.posix.dirname(normalizedPath), susp.symlink));
upsertArchiveEntry(entries, {
path: normalizedPath,
isDirectory: false,
size: 0,
mtimeMs: record.mtimeMs,
mode: susp.mode,View on GitHub (pinned to 9690622007)
Solutions
- Re-generate the image without directory relocation: mkisofs/xorriso with -r plus avoiding >8-level nesting (or use -joliet-long/UDF to carry deep paths)
- Flatten or restructure the source directory tree to at most 8 levels before creating the ISO
- Use an extraction tool that supports RR relocation (e.g. 7z, xorriso -osirrox) to get the files, then re-pack into a supported archive
- If you control the image source, disable deep-relocation (mkisofs -D, accepting the ISO limit) or enable UDF
Example fix
// before $ genisoimage -R -o img.iso deepTree/ # deep relocation dir created -> throws // after $ xorriso -as mkisofs -r -D -o img.iso deepTree/ # or restructure tree to <=8 levels
Defensive patterns
Strategy: fallback
Validate before calling
// detect deep relocation marker before reading: look for /RR_MOVED. or hidden relocation dir in listing
const names = await listIsoNames(image);
if (names.some(n => /RR_MOVED/i.test(n))) throw new Error('image uses Rock Ridge deep relocation'); Type guard
null
Try / catch
try {
entries = await readIsoEntries(image);
} catch (err) {
if (err instanceof ArchiveError && err.message.includes('relocated directory')) {
return extractWith7z(image); // relocation-aware extractor, then re-pack
}
throw err;
} Prevention
- Build ISOs with -D (no deep relocation) or keep trees <=8 levels
- Enable UDF (-udf) for deep directory trees
- Prefer xorriso for authoring; it handles deep trees without legacy RR relocation
When it happens
Trigger: Reading an ISO image (entry/traversal path in iso.ts around line 521) that contains a Rock Ridge relocated directory — i.e. a directory record carrying the CL (child link) SUSP entry marking it as moved to a deeper level — encountered while walking directory records.
Common situations: ISO images with directory nesting deeper than 8 levels produced by mkisofs' -hide-rr-moved-style relocation or modern -rr defaults on very deep trees, notably some Linux distribution trees and backup archives with deep paths.
Related errors
- --list-details, --exec, and --exec-batch are not supported b
- OpenAI explicit prompt caching is unsupported for ${model.pr
- no built-in uploader or serving adapter is implemented
- SFTP password injection is unsupported by the shared SSH tra
- --cache is not supported for openai-codex-responses because
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/130496906b502706.
Report an issue: GitHub.