can1357/oh-my-pi · error

Import source is neither file nor directory: ${target}

Error message

Import source is neither file nor directory: ${target}

What it means

`collectImportSources` stats the import target and accepts either a regular file or a directory (from which it collects `*.json` files). If the target exists but is neither — e.g. a fifo, socket, or device — it throws. (A nonexistent path fails earlier with ENOENT from `fs.stat` itself.)

Source

Thrown at packages/coding-agent/src/cli/auth-broker-cli.ts:520

		const providerId = CLIPROXY_TYPE_TO_PROVIDER[prefix];
		if (base.startsWith(`${prefix}-`) || base === prefix) return providerId;
	}
	return null;
}

function parseCliProxyExpiry(raw: string | undefined): number | null {
	if (!raw) return null;
	// CLIProxyAPI writes RFC3339-ish dates. `Date.parse` handles both `Z` and offsets.
	const ms = Date.parse(raw);
	if (!Number.isFinite(ms)) return null;
	return ms;
}

async function collectImportSources(target: string): Promise<string[]> {
	const stat = await fs.stat(target);
	if (stat.isFile()) return [target];
	if (!stat.isDirectory()) {
		throw new Error(`Import source is neither file nor directory: ${target}`);
	}
	const entries = await fs.readdir(target, { withFileTypes: true });
	const files: string[] = [];
	for (const entry of entries) {
		if (!entry.isFile()) continue;
		if (!entry.name.endsWith(".json")) continue;
		files.push(path.join(target, entry.name));
	}
	files.sort();
	return files;
}

async function loadImportPlan(
	target: string,
	overrideProvider: string | undefined,
	includeDisabled: boolean,
): Promise<{ entries: ImportPlanEntry[]; skipped: Array<{ file: string; reason: string }> }> {
	const files = await collectImportSources(target);

View on GitHub (pinned to 9690622007)

Solutions

  1. Pass a path to a regular credential JSON file or a directory containing `*.json` files.
  2. Remove or replace the broken symlink with a path to the real file/directory.
  3. Verify the target type with `stat <target>` before importing.

Example fix

// before
omp auth-broker import /tmp/creds.fifo   // neither file nor directory
// after
omp auth-broker import /tmp/credentials.json
Defensive patterns

Strategy: validation

Validate before calling

import * as fs from "node:fs/promises";
const stat = await fs.stat(target);
if (!stat.isFile() && !stat.isDirectory()) {
  throw new Error(`${target} must be a JSON file or a directory of *.json files`);
}
await runImport({ source: target });

Try / catch

try {
  await runImport({ source: target });
} catch (err) {
  if (err instanceof Error && err.message.startsWith("Import source is neither file nor directory")) {
    console.error("Pass a credential JSON file or a directory containing *.json exports.");
  } else throw err;
}

Prevention

When it happens

Trigger: `omp auth-broker import <target>` where `<target>` is a special file (fifo, socket, device) or a path that stat resolves to a non-file, non-directory type.

Common situations: Pointing import at a fifo/pipe created for streaming; a dangling or unusual symlink; passing a device path like `/dev/null` as the source.

Related errors


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/044f6a06e0c3c07c. Report an issue: GitHub.