can1357/oh-my-pi · error · Error
Destination option ${key} must be a string
Error message
Destination option ${key} must be a string What it means
requiredString validates that a destination runtime option exists and is a string, throwing a plain Error when the value is present but of the wrong type (e.g. number or boolean). It guards options like accountId, bucket, container, and authorizationToken before they reach the S3/B2/object-storage uploaders.
Source
Thrown at packages/coding-agent/src/blob-broker/uploaders-object-storage.ts:71
authorizationToken: string;
apiUrl: string;
downloadUrl: string;
}
interface B2Bucket {
bucketId: string;
bucketName: string;
bucketType: string;
}
interface B2UploadTarget {
uploadUrl: string;
authorizationToken: string;
}
function requiredString(config: DestinationRuntimeConfig, key: string): string {
const value = requireOption(config, key);
if (typeof value !== "string") throw new Error(`Destination option ${key} must be a string`);
return value;
}
function configuredPrefix(config: DestinationRuntimeConfig): string | undefined {
return optionString(config, "keyPrefix") ?? optionString(config, "prefix") ?? optionString(config, "path");
}
function objectKey(prefix: string | undefined, filename: string): string {
const cleanPrefix = prefix?.replaceAll("\\", "/").replace(/^\/+|\/+$/g, "");
return cleanPrefix ? `${cleanPrefix}/${filename}` : filename;
}
function encodePath(path: string): string {
return path
.split("/")
.map(segment =>
encodeURIComponent(segment).replace(
/[!'()*]/g,View on GitHub (pinned to 9690622007)
Solutions
- Quote the option value in the destination config so it is a JSON string: "bucket": "12345".
- Inspect the config with a JSON validator to find which option under Destination option <key> is non-string.
- If the option is genuinely numeric upstream, stringify it in the config layer before handing it to the broker.
- Check for config-generation code that passes raw numbers instead of String(id).
Example fix
// before
{ "destination": { "accountId": 123456, "bucket": 98765 } }
// after
{ "destination": { "accountId": "123456", "bucket": "98765" } } Defensive patterns
Strategy: validation
Validate before calling
const OPTION_KEYS = ["accountId", "bucket", "container", "uploadUrl", "authorizationToken"] as const;
for (const key of OPTION_KEYS) {
const v = config[key];
if (v !== undefined && typeof v !== "string") {
throw new Error(`config option ${key} must be a string, got ${typeof v}`);
}
} Type guard
function isStringOption(config: Record<string, unknown>, key: string): config is Record<string, string> {
return config[key] === undefined || typeof config[key] === "string";
} Try / catch
try {
const uploader = createObjectStorageUploader(destination, config);
} catch (err) {
if (err instanceof Error && err.message.startsWith("Destination option")) {
const key = err.message.match(/Destination option (\w+)/)?.[1];
console.error(`Fix config: option '${key}' must be quoted as a string`);
} else throw err;
} Prevention
- always quote IDs (account/bucket numbers) in destination configs
- run JSON schema validation over the config file at startup
- avoid hand-editing configs where editors auto-coerce digit-only values to numbers
- use a typed config loader that rejects non-string option values before upload time
When it happens
Trigger: A destination config supplies an option that requiredString reads (bucket, accountId, container, uploadUrl, authorizationToken, etc.) with a non-string JSON value — e.g. "bucket": 12345 or "uploadUrl": true — or a number-like ID entered without quotes.
Common situations: Config file edited by hand where a numeric account/bucket ID was written as a JSON number; programmatic config builder passing numbers; YAML/JSON type coercion turning an all-digit ID into a number.
Related errors
- 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 $
- cachedContent must not be blank
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/65db33e57341bc93.
Report an issue: GitHub.