can1357/oh-my-pi · error
Destination option ${key} must be a boolean
Error message
Destination option ${key} must be a boolean What it means
optionBoolean reads a boolean destination option and throws when the value is defined but not a boolean. Flags like direct, isPublic, preview, raw, and requireDirectMode are used as strict booleans; the runtime refuses truthy strings such as "yes" or "true" instead of guessing. This keeps config semantics unambiguous.
Source
Thrown at packages/coding-agent/src/blob-broker/uploader-runtime.ts:74
if (typeof value !== "string") throw new Error(`Destination option ${key} must be a string`);
return value;
}
/** Read a number option, returning a fallback when it is absent. */
export function optionNumber(config: DestinationRuntimeConfig, key: string, fallback?: number): number | undefined {
const value = config.options[key];
if (value === undefined) return fallback;
if (typeof value !== "number" || !Number.isFinite(value)) {
throw new Error(`Destination option ${key} must be a finite number`);
}
return value;
}
/** Read a boolean option, returning a fallback when it is absent. */
export function optionBoolean(config: DestinationRuntimeConfig, key: string, fallback?: boolean): boolean | undefined {
const value = config.options[key];
if (value === undefined) return fallback;
if (typeof value !== "boolean") throw new Error(`Destination option ${key} must be a boolean`);
return value;
}
/** Read a credential without exposing its value in an error. */
export function credentialString(config: DestinationRuntimeConfig, key: string): string | undefined {
const value = config.credentials[key];
return value === "" ? undefined : value;
}
/** Read a required credential without exposing its value in an error. */
export function requireCredential(config: DestinationRuntimeConfig, key: string): string {
const value = credentialString(config, key);
if (value === undefined) throw new Error(`Missing required destination credential: ${key}`);
return value;
}
/** Select the injected request implementation, or Bun's global fetch by default. */
export function fetchFor(config: DestinationRuntimeConfig): FetchImpl {View on GitHub (pinned to 9690622007)
Solutions
- Use a real boolean literal in config: `"direct": true`.
- Coerce env/CLI string values to booleans before building the options object (`value === "true"`).
- Verify the option key is the correct one for this destination; some flags only exist on certain uploaders.
Example fix
// before
{ "options": { "preview": "true" } }
// after
{ "options": { "preview": true } } Defensive patterns
Strategy: validation
Validate before calling
function assertBooleanOption(options: Record<string, unknown>, key: string): void {
const v = options[key];
if (v !== undefined && typeof v !== "boolean") throw new Error(`option ${key} must be a boolean`);
}
assertBooleanOption(config.options, "direct"); Type guard
const isBoolean = (v: unknown): v is boolean => typeof v === "boolean";
Try / catch
try {
uploader = createUploader(config);
} catch (err) {
if (String(err).includes("must be a boolean")) config.options.direct = config.options.direct === "true";
else throw err;
} Prevention
- Use true/false literals, never "true"/"false" strings, in config.
- When importing from env vars, convert explicitly: process.env.FLAG === "true".
- Validate the whole options object once at config load, not per uploader call.
When it happens
Trigger: Calling optionBoolean(config, key) — via requireDirectMode, isPublic, s3Defaults, direct, preview, or raw — when config.options[key] is a string ("true", "false"), a number (0/1), or null-like non-boolean value.
Common situations: Writing `"direct": "true"` in JSON config, env-var-derived options that stay strings, or CLI overrides injected as strings into an options object.
Related errors
- Destination option ${key} must be a string
- Destination option ${key} must be a finite number
- Invalid pattern: {err}
- Failed to load tree-sitter language: {err}
- ${destination} returned an invalid upload URL
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/c1a346e447803a29.
Report an issue: GitHub.