can1357/oh-my-pi · error · Error
images.urls.command is empty
Error message
images.urls.command is empty
What it means
createCommandUploader builds a BlobUploader from an argv template string (images.urls.command in config). After splitting the template, if no arguments remain the command is useless, so it throws immediately. This is a synchronous, configuration-time validation error.
Source
Thrown at packages/coding-agent/src/blob-broker/uploaders.ts:82
}
/** Last URL printed on stdout wins; uploader tools often log progress first. */
export function extractUploadUrl(stdout: string): string | null {
let last: string | null = null;
for (const match of stdout.matchAll(URL_PATTERN)) {
last = match[0].replace(/[)\],.'"]+$/, "");
}
return last;
}
/**
* Build an uploader from an argv template. Placeholders, substituted after
* splitting (paths with spaces stay one argument): `{file}` temp file path,
* `{mime}` MIME type, `{ext}` bare extension.
*/
export function createCommandUploader(template: string): BlobUploader {
const argvTemplate = splitCommandTemplate(template);
if (argvTemplate.length === 0) throw new Error("images.urls.command is empty");
if (!argvTemplate.some(arg => arg.includes("{file}"))) {
throw new Error("images.urls.command must reference {file}");
}
return {
destination: "command",
async upload(request: BlobUploadRequest): Promise<BlobPublication> {
const { bytes, mimeType, extension } = request;
const file = path.join(os.tmpdir(), `omp-blob-upload-${crypto.randomUUID()}.${extension}`);
await Bun.write(file, bytes);
try {
const argv = argvTemplate.map(arg =>
arg.replaceAll("{file}", file).replaceAll("{mime}", mimeType).replaceAll("{ext}", extension),
);
const cwd = getProjectDir();
if (!directoryIsEnterableSync(cwd)) {
throw new Error(`Project directory is not accessible: ${cwd}`);
}
const proc = Bun.spawn(argv, { stdin: "ignore", stdout: "pipe", stderr: "pipe", cwd });View on GitHub (pinned to 9690622007)
Solutions
- Set images.urls.command to a real command template, e.g. "curl -F 'file=@{file}' https://0x0.st"
- Remove the empty images.urls.command key if you do not want the command destination
- Check the config file section actually saved (empty string vs commented-out line)
- Validate the template contains {file} as well, since a non-empty template without {file} throws the next error
Example fix
// before
"urls": { "command": "" }
// after
"urls": { "command": "curl -sF 'file=@{file}' https://0x0.st" } Defensive patterns
Strategy: validation
Validate before calling
const cmd = config.images?.urls?.command;
if (typeof cmd !== "string" || cmd.trim().length === 0) {
throw new Error("images.urls.command must be a non-empty command template");
} Type guard
function hasCommandTemplate(c: unknown): c is { command: string } {
return typeof c === "object" && c !== null && typeof (c as { command?: unknown }).command === "string"
&& (c as { command: string }).command.trim().length > 0;
} Try / catch
try {
const uploader = createConfiguredUploader("command", config);
} catch (err) {
if (err instanceof Error && err.message === "images.urls.command is empty") {
// prompt user to fill images.urls.command in config
}
throw err;
} Prevention
- Never leave images.urls.command as an empty string; comment out the whole block instead
- Validate config at load time with a schema
- Include {file} whenever you set a command template
- Keep a working example command in config comments
When it happens
Trigger: Configuring images.urls.command as an empty string or whitespace-only string; the template consists solely of characters that splitCommandTemplate strips (quotes/spaces), yielding zero argv entries.
Common situations: Config placeholder left unfilled ("command": "") after copying a config template; YAML/TOML key present but value empty; quoting mistakes that collapse the value to nothing.
Related errors
- images.urls.command must reference {file}
- OMP_AUTH_BROKER_ACCOUNT_POOL_FILE contains an empty provider
- OMP_AUTH_BROKER_ACCOUNT_POOL_FILE contains a provider id wit
- ${name} path does not exist: ${trimmed}
- Anthropic thinking budget requires max_tokens greater than $
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/eb2669da32701b1e.
Report an issue: GitHub.