can1357/oh-my-pi · error · Error
Unsupported S3 destination: ${destination}
Error message
Unsupported S3 destination: ${destination} What it means
s3Defaults maps a destination id to S3 endpoint defaults and throws for destination ids it does not recognize in its switch, telling you the configured destination is not a supported S3 flavor. This is a programming/config-level guard: an unknown id reached the S3 uploader factory.
Source
Thrown at packages/coding-agent/src/blob-broker/uploaders-object-storage.ts:194
region: optionString(config, "region", "garage") ?? "garage",
pathStyle: optionBoolean(config, "pathStyle", true) ?? true,
publicBaseUrl: optionString(config, "publicBaseUrl"),
keyPrefix: configuredPrefix(config),
cacheControl: optionString(config, "cacheControl"),
};
case "backblaze-b2": {
const region = optionString(config, "region", "us-west-004") ?? "us-west-004";
return {
endpoint: endpointOption ?? `https://s3.${region}.backblazeb2.com`,
region,
pathStyle: optionBoolean(config, "pathStyle", false) ?? false,
publicBaseUrl: optionString(config, "publicBaseUrl"),
keyPrefix: configuredPrefix(config),
cacheControl: optionString(config, "cacheControl"),
};
}
default:
throw new Error(`Unsupported S3 destination: ${destination}`);
}
}
function createS3Uploader(destination: BlobDestinationId, config: DestinationRuntimeConfig): BlobUploader {
const defaults = s3Defaults(destination, config);
const settings: S3Settings = { ...defaults, bucket: requiredString(config, "bucket") };
const sessionToken = credentialString(config, "sessionToken");
const credentials: AwsCredentials = {
accessKeyId: requireCredential(config, "accessKeyId"),
secretAccessKey: requireCredential(config, "secretAccessKey"),
...(sessionToken ? { sessionToken } : {}),
};
const request = fetchFor(config);
return {
destination,
async upload(uploadRequest) {
const key = objectKey(settings.keyPrefix, fileNameFor(uploadRequest));View on GitHub (pinned to 9690622007)
Solutions
- Check the destination id for typos against the supported S3 destination list in uploaders-object-storage.ts.
- Use a supported S3-compatible id, or configure the generic S3 destination with explicit endpoint/region options.
- If you need a new provider, add a case to s3Defaults rather than reusing an existing id.
- Migrate legacy destination ids from older config versions to their current names.
Example fix
// before
{ "type": "s3", "provider": "digitalocean-spaces" } // not handled
// after
{ "type": "s3", "provider": "aws", "endpoint": "https://nyc3.digitaloceanspaces.com", "bucket": "images" } Defensive patterns
Strategy: validation
Validate before calling
const S3_DESTINATIONS = new Set(["aws", "cloudflare-r2", "wasabi", "minio", "generic-s3"]);
if (!S3_DESTINATIONS.has(destination)) {
console.warn(`'${destination}' has no S3 defaults; supply endpoint/region explicitly or pick a supported id`);
} Type guard
function isSupportedS3Destination(id: string): boolean {
return ["aws", "cloudflare-r2", "wasabi", "minio", "generic-s3"].includes(id);
} Try / catch
try {
const uploader = createS3Uploader(destination, config);
} catch (err) {
if (err instanceof Error && err.message.startsWith("Unsupported S3 destination")) {
console.error(`Unknown S3 provider '${destination}'; check supported ids`);
} else throw err;
} Prevention
- source destination type ids from a shared enum/constants module
- validate the whole destination config against the supported-provider list at startup
- when adding a new S3-compatible provider, add the s3Defaults case in the same change
- grep old configs for deprecated provider ids during upgrades
When it happens
Trigger: createS3Uploader is invoked with a BlobDestinationId that falls through the switch's default arm — i.e. an id that is not one of the supported S3-compatible services (aws, cloudflare-r2, wasabi, etc.).
Common situations: Typo in the destination type string in config; new S3-compatible provider added to config before support exists in the broker; destination id from an older config version that was renamed.
Related errors
- Destination option ${key} must be a string
- Backblaze B2 bucket not found: ${bucketName}
- No model configured
- Azure OpenAI base URL is required. Set AZURE_OPENAI_BASE_URL
- Cannot register custom API "${api}": built-in API names are
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/64d1cc5ca07ef40d.
Report an issue: GitHub.